Bug 57831 - Fragmented JSON Messages Causing IllegalStateException
Summary: Fragmented JSON Messages Causing IllegalStateException
Status: RESOLVED DUPLICATE of bug 57776
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: WebSocket (show other bugs)
Version: 8.0.21
Hardware: All All
: P2 critical (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2015-04-18 22:43 UTC by Kenneth Gendron
Modified: 2015-04-19 07:38 UTC (History)
0 users

Message that causes the failure (52.53 KB, text/plain)
2015-04-18 22:43 UTC, Kenneth Gendron

Note You need to log in before you can comment on or make changes to this bug.
Description Kenneth Gendron 2015-04-18 22:43:53 UTC
Created attachment 32660 [details]
Message that causes the failure

Tomcat 8.0.21 (not 8.0.20 or earlier) is throwing an IllegalStateException for JSON messages.  Below is the exception being thrown.

Exception in thread "WebSocketServer-localhost-/temp-4" java.lang.IllegalStateException: When sending a fragmented message, all fragments bust be of the same type
        at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:411)
        at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.endMessage(WsRemoteEndpointImplBase.java:366)
        at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$IntermediateMessageHandler.onResult(WsRemoteEndpointImplBase.java:513)
        at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer$OnResultRunnable.run(WsRemoteEndpointImplServer.java:247)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Attached is the message that is causing the issue.

Looking at the top few lines:

  "context": "4IVS04",
  "data": {
    "enterfornext": true,
    "inputs": [
        "autocomplete": 3,
        "desc": "Enter Tool: ",
        "options": [

If the entire "DNOTCH10" line is removed, the message can be transmitted by Tomcat; however, even adding a single "illegal" character in the JSON after this line is removed causes the error to be thrown.

It appears Tomcat is analyzing the fragments its sending and determining that some cannot be sent because they are not legitimate JSON (or something to that affect).

Again, version 8.0.20 and below does not have this issue.



P.S. I can provide the test web app to demonstrate this.
Comment 1 Kenneth Gendron 2015-04-18 23:42:14 UTC
The changes to PerMessageDeflate class have caused the opCode for the subsequent fragments to change from OPCODE_TEXT to OPCODE_CONTINUATION (i.e. they are transformed).  This cause the "Util.isText(mp.getOpCode())" code at line 406 of the WsRemoteEndpointImplBase class to return false.  

I suspect other things are being affected by the PerMessageDeflate class changes, most notably the other send methods; however, adding "|| Util.isContinuation(mp.getOpCode())" will fix this.
Comment 2 Kenneth Gendron 2015-04-18 23:49:39 UTC
Line 451 in PerMessageDeflate.  Just as an aside this should be set to Constants.OPCODE_CONTINUATION, not zero "0" explicitly.
Comment 3 Kenneth Gendron 2015-04-19 00:39:32 UTC
The fix I proposed would have broken binary transmission.  Instead simply changing line 410 in WsRemoteEndpointImplBase to "if (text != isText && mp.getOpCode() != Constants.OPCODE_CONTINUATION) {" should work.  It does essentially break the implementations ability to detect changes in type but I do not see a ready alternative.
Comment 4 Mark Thomas 2015-04-19 07:38:21 UTC

*** This bug has been marked as a duplicate of bug 57776 ***