Bug 62596 - WsWebSocketContainer#connectToServer throws BufferOverflowException
Summary: WsWebSocketContainer#connectToServer throws BufferOverflowException
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: WebSocket (show other bugs)
Version: 8.5.x-trunk
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2018-08-03 12:43 UTC by erik.mccallum
Modified: 2018-08-08 06:34 UTC (History)
0 users

Contrived example to trigger BufferOverflowException in WsWebSocketContainer#connectToServer (1.90 KB, text/plain)
2018-08-03 12:43 UTC, erik.mccallum

Note You need to log in before you can comment on or make changes to this bug.
Description erik.mccallum 2018-08-03 12:43:04 UTC
Created attachment 36071 [details]
Contrived example to trigger BufferOverflowException in WsWebSocketContainer#connectToServer

WsWebSocketContainer#connectToServer throws BufferOverflowException when headers supplied by ClientEndpointConfig.Configurator#beforeRequest are too large.

Exception in thread "main" java.nio.BufferOverflowException
	at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:189)
	at java.nio.ByteBuffer.put(ByteBuffer.java:859)
	at org.apache.tomcat.websocket.WsWebSocketContainer.addHeader(WsWebSocketContainer.java:755)
	at org.apache.tomcat.websocket.WsWebSocketContainer.createRequest(WsWebSocketContainer.java:736)
	at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServerRecursive(WsWebSocketContainer.java:275)
	at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:195)

In our application, we are forwarding an Authorization header/token of close to 4000 bytes, which when combined with other headers results in a request larger than the 4096 allocated to the ByteBuffer in WsWebSocketContainer#createRequest.

Suggest making this buffer size configurable via a new setting in org.apache.tomcat.websocket.Constants.  I can contribute a fix if that is appropriate.  Our local patch has the following in Constants:

    static final int WS_UPGRADE_REQUEST_SIZE = Integer.getInteger(
            "org.apache.tomcat.websocket.WS_UPGRADE_REQUEST_SIZE", 8 * 1024)

So, a new default buffer size of 8k, and the option of setting a system property if it needs to be bumped up further.

I've attached some code that will trigger the exception.
Comment 1 Mark Thomas 2018-08-07 19:43:42 UTC
I'm leaning more towards simply auto-expanding the buffer until it is big enough. I'm not concerned about memory issues as the user is in control of the headers they send.
Comment 2 erik.mccallum 2018-08-08 03:31:43 UTC
That makes sense.
Comment 3 Mark Thomas 2018-08-08 06:34:22 UTC
Fixed in:
- trunk for 9.0.11 onwards
- 8.5.x for 8.5.33 onwards
- 7.0.x for 7.0.91 onwards