Hi,
We are trying to implement websockets in our plugin UI and it is giving 502 error.
To confirm on the support, we had taken 8.0U1 SDK sample and deployed it on Client 8.0U1 and found that same error is coming for sample plugin as well.
Could you please confirm/help on fixing the sample?
we were able to establish the socket connection directly without going through the plugin reverse proxied manifest/backend server(htmlClientSdk.app.getPluginBackendInfo) address.
I remember the recommendation is to tunnel all interaction through proxied backend server URL .
Does establishing socket connection directly to plugin backend is acceptable or not?
Any implication on plugin certification?
Error:
vSphere Client version 8.0.0.10000
Sample jar Server log:
2023-11-09 02:21:38.135 ERROR 7164 --- [io-8443-exec-17] c.v.s.r.w.WebSocketMessageHandler : Transport error
java.io.IOException: Unable to unwrap data, invalid status [CLOSED]
at org.apache.tomcat.util.net.SecureNioChannel.read(SecureNioChannel.java:632) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1257) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1230) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1200) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:72) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_392-392]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_392-392]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at java.lang.Thread.run(Thread.java:750) [na:1.8.0_392-392]
2023-11-09 02:21:38.135 ERROR 7164 --- [io-8443-exec-17] c.v.s.r.w.WebSocketMessageHandler : Transport error
java.io.IOException: java.io.IOException: Unable to wrap data, invalid status [CLOSED]
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:315) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:258) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:592) [tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:480) [tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.WsSession.close(WsSession.java:445) [tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.closeInternal(StandardWebSocketSession.java:236) [spring-websocket-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.socket.adapter.AbstractWebSocketSession.close(AbstractWebSocketSession.java:136) [spring-websocket-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at com.vmware.sample.remote.websocket.WebSocketMessageHandler.handleTransportError(WebSocketMessageHandler.java:66) [classes!/:na]
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleTransportError(WebSocketHandlerDecorator.java:80) [spring-websocket-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleTransportError(LoggingWebSocketHandlerDecorator.java:64) [spring-websocket-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleTransportError(ExceptionWebSocketHandlerDecorator.java:68) [spring-websocket-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.onError(StandardWebSocketHandlerAdapter.java:156) [spring-websocket-5.0.7.RELEASE.jar!/:5.0.7.RELEASE]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.onError(WsHttpUpgradeHandler.java:216) [tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:152) [tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_392-392]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_392-392]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.31.jar!/:8.5.31]
at java.lang.Thread.run(Thread.java:750) [na:1.8.0_392-392]
Caused by: java.io.IOException: Unable to wrap data, invalid status [CLOSED]
at org.apache.tomcat.util.net.SecureNioChannel.write(SecureNioChannel.java:675) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1276) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:670) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.SocketWrapperBase.flushBlocking(SocketWrapperBase.java:607) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.util.net.SocketWrapperBase.flush(SocketWrapperBase.java:597) ~[tomcat-embed-core-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:96) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:494) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendMessageBlock(WsRemoteEndpointImplBase.java:309) ~[tomcat-embed-websocket-8.5.31.jar!/:8.5.31]
... 22 common frames omitted
Hi, Thank you for catching this bug.
I managed to reproduce the issue. It is not a constant bug so it was interesting task to find out the problem.
Before I give the explanation what goes wrong, just wanted to say that the WS should go through the proxied url as well.
Problem:
What is the current workflow:
1) A request is sent to the java code to generate a secure token. (ref: messaging-service.ts, WebSocketSessionTicketService)
2) Then the UI uses this token when creating WS (ref: messaging-service.ts)
3) The java code checks if this is the token that was previously generated. (ref WebSocketSessionTicketService::validateTicket)
The problem is at step 2 where the token sent from the UI is not encoded and the app tries to encode it (for example changing + to a space character which breaks the workflow).
This can be solved by encoding the token before passing it to the WebSocket.
The solution should be done in the messaging-service.ts by encoding the sessionTicket before sending it to the backend with the WS.
Since the WebSocket JS API does not allow header modification, this might be the only way to fix this from the JS side. Possible solution is to do the needed encoding transformations during ticket generation but requires much more coding.
Example fix:
const anchorElement = document.createElement('a');
anchorElement.href = 'messaging' +
`?session-ticket=${encodeURIComponent(sessionTicket)}`; // HERE IS THE FIX
const messagingUrl =
`wss://${anchorElement.host}${anchorElement.pathname}${anchorElement.search}`;
Try out this fix to verify if it fixes the issue that you are observing.
Thanks,
Martin
Thanks. I will try out the fix and update.
Can you clarify on these queries?
There are no implications on plugin certification.
I am not sure if there won't be any CORS problems and issues with self signed certificates when using the WSS directly to the backend server without the proxied path.