Description
During migration from Spring 6.0 and replacing JettyWebSocketClient
with StandardWebSocketClient
we noticed that StandardWebSocketSession
incorrectly returns a remote port instead of a local port from WebSocketSession#getLocalAddress()
for the client WS session. Old removed JettyWebSocketSession
was implementing this method correctly. It was returning the port of the local socket of the underlying TCP connection.
This problem comes from the following implementation in StandardWebsocketClient
which is obviously erroneous:
@Override
protected CompletableFuture<WebSocketSession> executeInternal(WebSocketHandler webSocketHandler,
HttpHeaders headers, final URI uri, List<String> protocols,
List<WebSocketExtension> extensions, Map<String, Object> attributes) {
int port = getPort(uri);
InetSocketAddress localAddress = new InetSocketAddress(getLocalHost(), port);
InetSocketAddress remoteAddress = new InetSocketAddress(uri.getHost(), port);
StandardWebSocketSession session = new StandardWebSocketSession(headers,
attributes, localAddress, remoteAddress);
Client WS Session shouldn't use the same port value for both the local and remote addresses.
There was a previous report about this bug and regression that was incorrectly closed for being a question: #22395
Workaround
To work around this bug, instead of
WebSocketSession session = ...
InetSocketAddress localAddress = session.getLocalAddress();
users should do
InetSocketAddress localAddress = (InetSocketAddress)((JakartaWebSocketSession)(((StandardWebSocketSession)
session).getNativeSession())).getCoreSession().getLocalAddress();
when are using Jakarta WS implementation.