Skip to content

Commit

Permalink
Allow WebSocket over HTTP CONNECT
Browse files Browse the repository at this point in the history
Closes gh-34044
  • Loading branch information
rstoyanchev committed Feb 3, 2025
1 parent 1cea1fe commit f477c16
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -66,6 +67,9 @@
*/
public class HandshakeWebSocketService implements WebSocketService, Lifecycle {

// For WebSocket upgrades in HTTP/2 (see RFC 8441)
private static final HttpMethod CONNECT_METHOD = HttpMethod.valueOf("CONNECT");

private static final String SEC_WEBSOCKET_KEY = "Sec-WebSocket-Key";

private static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol";
Expand Down Expand Up @@ -201,9 +205,9 @@ public Mono<Void> handleRequest(ServerWebExchange exchange, WebSocketHandler han
HttpMethod method = request.getMethod();
HttpHeaders headers = request.getHeaders();

if (HttpMethod.GET != method) {
if (HttpMethod.GET != method && CONNECT_METHOD != method) {
return Mono.error(new MethodNotAllowedException(
request.getMethod(), Collections.singleton(HttpMethod.GET)));
request.getMethod(), Set.of(HttpMethod.GET, CONNECT_METHOD)));
}

if (!"WebSocket".equalsIgnoreCase(headers.getUpgrade())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -77,6 +78,9 @@
*/
public abstract class AbstractHandshakeHandler implements HandshakeHandler, Lifecycle {

// For WebSocket upgrades in HTTP/2 (see RFC 8441)
private static final HttpMethod CONNECT_METHOD = HttpMethod.valueOf("CONNECT");

private static final boolean tomcatWsPresent;

private static final boolean jettyWsPresent;
Expand Down Expand Up @@ -210,11 +214,12 @@ public final boolean doHandshake(ServerHttpRequest request, ServerHttpResponse r
logger.trace("Processing request " + request.getURI() + " with headers=" + headers);
}
try {
if (HttpMethod.GET != request.getMethod()) {
HttpMethod httpMethod = request.getMethod();
if (HttpMethod.GET != httpMethod && CONNECT_METHOD != httpMethod) {
response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
response.getHeaders().setAllow(Collections.singleton(HttpMethod.GET));
response.getHeaders().setAllow(Set.of(HttpMethod.GET, CONNECT_METHOD));
if (logger.isErrorEnabled()) {
logger.error("Handshake failed due to unexpected HTTP method: " + request.getMethod());
logger.error("Handshake failed due to unexpected HTTP method: " + httpMethod);
}
return false;
}
Expand Down

0 comments on commit f477c16

Please sign in to comment.