Skip to content

Commit 292ee15

Browse files
committed
fixes #11 Handling handshake properly with Sec-WebSocket-Protocol
1 parent af40d3f commit 292ee15

File tree

1 file changed

+31
-6
lines changed

1 file changed

+31
-6
lines changed

websocket-router/src/main/java/com/networknt/websocket/router/WebSocketRouterHandler.java

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,24 @@
1212
import io.undertow.server.HttpHandler;
1313
import io.undertow.server.HttpServerExchange;
1414
import io.undertow.util.Headers;
15+
import io.undertow.util.HttpString;
1516
import io.undertow.util.PathMatcher;
1617
import io.undertow.websockets.WebSocketConnectionCallback;
1718
import io.undertow.websockets.WebSocketProtocolHandshakeHandler;
18-
import io.undertow.websockets.client.WebSocketClient;
19+
import io.undertow.websockets.client.WebSocketClientNegotiation;
1920
import io.undertow.websockets.core.WebSocketChannel;
21+
import io.undertow.websockets.core.protocol.Handshake;
22+
import io.undertow.websockets.core.protocol.version07.Hybi07Handshake;
23+
import io.undertow.websockets.core.protocol.version08.Hybi08Handshake;
24+
import io.undertow.websockets.core.protocol.version13.Hybi13Handshake;
2025
import io.undertow.websockets.spi.WebSocketHttpExchange;
2126
import org.slf4j.Logger;
2227
import org.slf4j.LoggerFactory;
2328

2429
import java.io.IOException;
2530
import java.net.URI;
2631
import java.net.URISyntaxException;
27-
import java.util.Map;
32+
import java.util.*;
2833
import java.util.concurrent.ConcurrentHashMap;
2934

3035
public class WebSocketRouterHandler implements MiddlewareHandler, WebSocketConnectionCallback {
@@ -69,7 +74,17 @@ public void handleRequest(HttpServerExchange exchange) throws Exception {
6974
if (isWsRequest) {
7075
// Delegate to Undertow's WebSocketProtocolHandshakeHandler
7176
// which handles the upgrade and calls our onConnect callback
72-
new WebSocketProtocolHandshakeHandler(this).handleRequest(exchange);
77+
String protocolHeader = exchange.getRequestHeaders().getFirst("Sec-WebSocket-Protocol");
78+
if (protocolHeader != null) {
79+
Set<String> subprotocols = new LinkedHashSet<>(Arrays.asList(protocolHeader.split(",")));
80+
Collection<Handshake> handshakes = new ArrayList<>();
81+
handshakes.add(new Hybi13Handshake(subprotocols, false));
82+
handshakes.add(new Hybi08Handshake(subprotocols, false));
83+
handshakes.add(new Hybi07Handshake(subprotocols, false));
84+
new WebSocketProtocolHandshakeHandler(handshakes, this).handleRequest(exchange);
85+
} else {
86+
new WebSocketProtocolHandshakeHandler(this).handleRequest(exchange);
87+
}
7388
} else {
7489
// Not a websocket request for us, pass to next handler
7590
Handler.next(exchange, next);
@@ -191,13 +206,23 @@ public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel)
191206
}
192207

193208
/* create new connection to downstream */
194-
final var webSocketConnection = new WebSocketClient.ConnectionBuilder(
209+
String subprotocol = exchange.getRequestHeader("Sec-WebSocket-Protocol");
210+
List<String> subprotocols = subprotocol != null ? Collections.singletonList(subprotocol) : Collections.emptyList();
211+
WebSocketClientNegotiation negotiation = new WebSocketClientNegotiation(subprotocols, Collections.emptyList()) {
212+
@Override
213+
public void beforeRequest(Map<String, List<String>> headers) {
214+
if (subprotocol != null) {
215+
headers.put("Sec-WebSocket-Protocol", Collections.singletonList(subprotocol));
216+
}
217+
}
218+
};
219+
220+
final var webSocketConnection = new io.undertow.websockets.client.WebSocketClient.ConnectionBuilder(
195221
channel.getWorker(),
196222
channel.getBufferPool(),
197223
new URI(targetUri)
198-
);
224+
).setClientNegotiation(negotiation);
199225
final var outChannel = webSocketConnection.connect().get();
200-
201226
outChannel.setAttribute(WsAttributes.CHANNEL_GROUP_ID, channelId);
202227
outChannel.setAttribute(WsAttributes.CHANNEL_DIRECTION, WsProxyClientPair.SocketFlow.PROXY_TO_DOWNSTREAM);
203228
outChannel.getReceiveSetter().set(new WebSocketSessionProxyReceiveListener(CHANNELS));

0 commit comments

Comments
 (0)