ArrayIndexOutOfBoundsException when connecting to WebSocket via Weberknecht


Ask by : caw November 04, 2012 02:39

I'm trying to connect to a WebSocket via Weberknecht Java library. When the Java client tries to create the connection, I get the following error message:

W/System.err(805): java.lang.ArrayIndexOutOfBoundsException: length=1000; index=1000
W/System.err(805): at ...WebSocketConnection.connect(WebSocketConnection.java:86)

Here is the part which causes the problem:

public void connect() throws WebSocketException {
    try {
        if (connected) {
            throw new WebSocketException("already connected");
        }

        socket = createSocket();
        input = new DataInputStream(socket.getInputStream());
        output = new PrintStream(socket.getOutputStream());

        output.write(handshake.getHandshake());

        boolean handshakeComplete = false;
        int len = 10000;
        byte[] buffer = new byte[len];
        int pos = 0;
        ArrayList<String> handshakeLines = new ArrayList<String>();

        while (!handshakeComplete) {
            int b = input.read();
            buffer[pos] = (byte) b; // THIS LINE CAUSES THE EXCEPTION
            pos += 1;

            if (buffer[pos - 1] == 0x0A && buffer[pos - 2] == 0x0D) {
                String line = new String(buffer, "UTF-8");
                if (line.trim().equals("")) {
                    handshakeComplete = true;
                } else {
                    handshakeLines.add(line.trim());
                }

                buffer = new byte[len];
                pos = 0;
            }
        }

What could cause this issue? Is it that this client library may not comply with the WebSocket version that the server uses?

The issue over there at Weberknecht has not been solved yet. I want to ask this question here because it seems to be quite a general problem (reading WebSocket headers and handshake data).

View original question

Answer by : Andrew T FinnellNovember 04, 2012 02:33

The code needs to check for -1 from input.read() to denote the connection hitting EOF.

Also I will assume based on the same bit of code that if a handshake hasn't been reaching after 10000 bytes it is an invalid handshake.

while (!handshakeComplete) {
            int b = input.read();

            if (b == -1)
                throw new WebSocketException ("Connected closed.");                

            if (pos == buffer.length)
                throw new WebSocketException ("Invalid handshake.");

            buffer[pos] = (byte) b; // THIS LINE CAUSES THE EXCEPTION
            pos += 1;

            if (buffer[pos - 1] == 0x0A && buffer[pos - 2] == 0x0D) {
                String line = new String(buffer, "UTF-8");
                if (line.trim().equals("")) {
                    handshakeComplete = true;
                } else {
                    handshakeLines.add(line.trim());
                }

                buffer = new byte[len];
                pos = 0;
            }
        }

Update

Here is a better implementation:

public void connect() throws WebSocketException {
    try {
        if (connected) {
            throw new WebSocketException("already connected");
        }

        socket = createSocket();
        input = new DataInputStream(socket.getInputStream());
        output = new PrintStream(socket.getOutputStream());

        output.write(handshake.getHandshake());

        boolean handshakeComplete = false;

        ArrayList<String> handshakeLines = new ArrayList<String>();

        BufferedReader reader = new BufferedReader(input);

        String handshakeData;
        while ((handshakeData = reader.readLine()) != null) {
            if (handshakeData.trim().equals("")) {
               handshakeComplete = true;
               break;
            }
            handshakeLines.add(handshakeData);
        }

        if (!handshakeComplete)
            throw new WebSocketException ("Failed to establish handshake.");
View original answer