I want to proxy WebSocket Connections through a Nuxt 3 Nitro Server to enrich it with Session information for authentication. I managed to get it working to a point, where the server intercepts the request, enriches it with an Authorization-Header and proxies it to a Spring Boot Backend. But the Backend is not able to process the request properly. At least thats my interpretation. In my Backend logs I have the following Log entries:
2024-11-16T12:06:31.433+01:00 DEBUG 10368 --- [nio-3001-exec-1] o.s.web.servlet.DispatcherServlet : GET "/ws", parameters={}
2024-11-16T12:06:31.436+01:00 DEBUG 10368 --- [nio-3001-exec-1] o.s.w.s.s.s.WebSocketHandlerMapping : Mapped to org.springframework.web.socket.server.support.WebSocketHttpRequestHandler@3d20e575
2024-11-16T12:06:31.441+01:00 DEBUG 10368 --- [nio-3001-exec-1] o.s.w.s.s.s.WebSocketHttpRequestHandler : GET /ws
2024-11-16T12:06:31.454+01:00 DEBUG 10368 --- [nio-3001-exec-1] o.s.web.servlet.DispatcherServlet : Completed 101 SWITCHING_PROTOCOLS
2024-11-16T12:06:31.461+01:00 DEBUG 10368 --- [nio-3001-exec-1] s.w.s.h.LoggingWebSocketHandlerDecorator : New StandardWebSocketSession[id=29da51eb-03a2-0697-900f-278000eff67a, uri=ws://localhost:3001/ws]
2024-11-16T12:06:31.463+01:00 DEBUG 10368 --- [nio-3001-exec-1] s.w.s.h.LoggingWebSocketHandlerDecorator : Transport error in StandardWebSocketSession[id=29da51eb-03a2-0697-900f-278000eff67a, uri=ws://localhost:3001/ws]
java.io.EOFException: null
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1296) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1184) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:74) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:184) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:164) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:152) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:57) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
at java.base/java.lang.Thread.run(Thread.java:1570) ~[na:na]
2024-11-16T12:06:31.467+01:00 DEBUG 10368 --- [nio-3001-exec-1] s.w.s.h.LoggingWebSocketHandlerDecorator : StandardWebSocketSession[id=29da51eb-03a2-0697-900f-278000eff67a, uri=ws://localhost:3001/ws] closed with CloseStatus[code=1006, reason=null]
2024-11-16T12:06:31.467+01:00 DEBUG 10368 --- [nio-3001-exec-1] o.s.w.s.m.SubProtocolWebSocketHandler : Clearing session 29da51eb-03a2-0697-900f-278000eff67a
2024-11-16T12:06:31.470+01:00 DEBUG 10368 --- [nboundChannel-2] org.springframework.web.SimpLogging : Processing DISCONNECT session=29da51eb-03a2-0697-900f-278000eff67a
2024-11-16T12:06:31.470+01:00 DEBUG 10368 --- [tboundChannel-1] o.s.w.s.m.SubProtocolWebSocketHandler : No session for GenericMessage [payload=byte[0], headers={simpMessageType=DISCONNECT_ACK, simpDisconnectMessage=GenericMessage [payload=byte[0], headers={simpMessageType=DISCONNECT, stompCommand=DISCONNECT, simpSessionAttributes={org.springframework.messaging.simp.SimpAttributes.COMPLETED=true}, simpSessionId=29da51eb-03a2-0697-900f-278000eff67a}], simpSessionId=29da51eb-03a2-0697-900f-278000eff67a}]
2024-11-16T12:07:25.523+01:00 INFO 10368 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 1 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 3], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
I created a minimal reproducible sample here: https://github.com/r4id4h/ws-repro.git
Why is the connection not established? In the sample there are two buttons. One is establishing the connection using the proxy and the other one directly. The direct connection is working but the proxy is not. What am I missing here?