engine.io-server-java icon indicating copy to clipboard operation
engine.io-server-java copied to clipboard

Polling transport malformed request body on large requests

Open Lahe opened this issue 3 years ago • 5 comments

Received this error when sending large text content via polling transport:

WARN  [2021-12-14 09:31:35,188] io.socket.parser.IOParser: An error occured while retrieving data from JSONTokener
! org.json.JSONException: Unterminated string at 7675 [character 7676 line 1]
! at org.json.JSONTokener.syntaxError(JSONTokener.java:507)
! at org.json.JSONTokener.nextString(JSONTokener.java:320)
! at org.json.JSONTokener.nextValue(JSONTokener.java:428)
! at org.json.JSONObject.<init>(JSONObject.java:233)
! at org.json.JSONTokener.nextValue(JSONTokener.java:431)
! at org.json.JSONObject.<init>(JSONObject.java:252)
! at org.json.JSONTokener.nextValue(JSONTokener.java:431)
! at org.json.JSONArray.<init>(JSONArray.java:125)
! at org.json.JSONTokener.nextValue(JSONTokener.java:434)
! at io.socket.parser.IOParser$Decoder.decodeString(IOParser.java:183)
! at io.socket.parser.IOParser$Decoder.add(IOParser.java:92)
! at io.socket.socketio.server.SocketIoClient.lambda$setup$2(SocketIoClient.java:161)
! at io.socket.emitter.Emitter.emit(Emitter.java:123)
! at io.socket.engineio.server.EngineIoSocket.emit(EngineIoSocket.java:185)
! at io.socket.engineio.server.EngineIoSocket.onPacket(EngineIoSocket.java:397)
! at io.socket.engineio.server.EngineIoSocket.lambda$setTransport$10(EngineIoSocket.java:300)
! at io.socket.emitter.Emitter.emit(Emitter.java:123)
! at io.socket.engineio.server.Transport.onPacket(Transport.java:104)
! at io.socket.engineio.server.transport.Polling.lambda$onData$1(Polling.java:197)
! at io.socket.engineio.parser.ParserV4.decodePayload(ParserV4.java:95)
! at io.socket.engineio.server.transport.Polling.onData(Polling.java:192)
! at io.socket.engineio.server.transport.Polling.onDataRequest(Polling.java:282)
! at io.socket.engineio.server.transport.Polling.onRequest(Polling.java:99)
! at io.socket.engineio.server.EngineIoSocket.onRequest(EngineIoSocket.java:213)
! at io.socket.engineio.server.EngineIoServer.handleRequest(EngineIoServer.java:168)
! at app.servlets.SocketIoServlet.service(SocketIoServlet.java:37)

Seems that using inputStream.read() in io.socket.engineio.server.transport.Polling.onDataRequest to stringify a large request body malforms the string.

Replacing

//noinspection ResultOfMethodCallIgnored
inputStream.read(mReadBuffer, 0, mReadBuffer.length);

with

inputStream.readLine(mReadBuffer, 0, mReadBuffer.length);

produced a valid string.

Alternatively, using a BufferedReader with request.getReader() seemed to work too.

StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
    buffer.append(line);
    buffer.append(System.lineSeparator());
}
String data = buffer.toString()

Lahe avatar Apr 07 '22 14:04 Lahe

Can you provide me with a sample payload? If that's not possible, can you tell me the size of the payload in bytes you were using when you got the error.

trinopoty avatar Apr 08 '22 16:04 trinopoty

I tested with 25 paragraphs of Lorem ipsum encoded in base64 but any payload over ~7700 bytes causes it.

Lahe avatar Apr 08 '22 20:04 Lahe

I'm unable to replicate this issue. I regularly transfer ~2MB of data on my application over websocket without issues. Can you check if you're using websocket or polling. Also, what browser and client library version are you using?

trinopoty avatar Apr 12 '22 17:04 trinopoty

Sorry, forgot to elaborate that it only happens when forcing polling transport mode on client side.

Lahe avatar Apr 12 '22 18:04 Lahe

Hi, The latest version improves reading the http stream, please try it out.

trinopoty avatar Aug 02 '23 15:08 trinopoty