VMware {code} Community
kumar_t
Enthusiast
Enthusiast

Remote plugin sample Websocket not working

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:

kumar_t_0-1699520065980.png

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

Labels (2)
Tags (1)
0 Kudos
3 Replies
stoevm
VMware Employee
VMware Employee

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

0 Kudos
kumar_t
Enthusiast
Enthusiast

Thanks. I will try out the fix and update.

Can you clarify on these queries?

  • Does establishing web socket connection directly to  backend IP (not using plugin reverse proxied) is acceptable or not? Any implication on plugin certification?
0 Kudos
stoevm
VMware Employee
VMware Employee

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.

0 Kudos