3

I have a micro-services application where I need to use WebSockets for one of the features. The browser connects to the API gateway, which then needs to forward the WebSocket request to the appropriate micro-service. To implement this, Spring's StandardWebSocketClient is used in the API gateway. The API gateway acts as a proxy for WebSocket requests.

My application uses OAuth for authentication, so when the WebSocket request is proxied in the API gateway, I need to pass on the OAuth2 token as well. When the StandardWebSocketClient issues the CONNECT request using Tomcat, I get a BufferOverflowException, because the bearer token does not seem to fit into the buffer used by Tomcat.

By looking at the Tomcat source code, the buffer size seems to be limited to 4096 bytes. See: https://github.com/apache/tomcat/blob/8fd5d6273099c504e1739080c07cf4d33cff89bf/java/org/apache/tomcat/websocket/WsWebSocketContainer.java#L717

Is there a workaround to overcome this limitation somehow?

  • You might be able to find some configurations, such as this one (https://stackoverflow.com/a/10848475/5197662) to increase buffer size. Do a little more search on that and I'm sure you will find good configuraition. Also, you might want to increase message buffer size in websocket server configuration code. – Sepehr GH May 16 '18 at 05:22

2 Answers2

0

Seeing this as well, due to large token in Authorization header. Using Tomcat 8.5.x

The buffer for constructing the HTTP request is hardcoded as 4096 bytes. I don't see any way around it - I think Tomcat needs to be updated with a larger, or configurable, buffer for the connection upgrade request.

I've submitted a bug report for Tomcat - https://bz.apache.org/bugzilla/show_bug.cgi?id=62596 - so hopefully should be addressed soon.

0

If you can control your websocket server program, you can set the buffer size in onOpen() method for each new connection from websocket client.

@ServerEndpoint("/endpoint1")
public class Server {

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("onOpen::" + session.getId());
        // eg:
        session.setMaxBinaryMessageBufferSize(4 * 1024 * 1024);
        session.setMaxTextMessageBufferSize(5 * 1024 * 1024);

    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("onClose::" + session.getId());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println(session.getId() + " message=" + message);
    }
}

But it seems If you set buffer size > 4m, you may get a warning about memory leak. Tested in Tomcat8.

Snkpty
  • 21
  • 2