Skip to content

Commit 3e1096f

Browse files
committed
Add helper method to determine if request can be upgraded to websocket.
Vert.x Web And Vert.x HTTP Proxy have similar code. This method covers all cases and can be reused. Signed-off-by: Thomas Segismont <[email protected]>
1 parent 6ddadec commit 3e1096f

File tree

2 files changed

+78
-4
lines changed

2 files changed

+78
-4
lines changed

src/main/java/io/vertx/core/http/impl/HttpUtils.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,4 +1016,24 @@ public static boolean isValidHostAuthority(String host) {
10161016
int len = host.length();
10171017
return HostAndPortImpl.parseHost(host, 0, len) == len;
10181018
}
1019+
1020+
public static boolean canUpgradeToWebSocket(HttpServerRequest req) {
1021+
if (req.version() != io.vertx.core.http.HttpVersion.HTTP_1_1) {
1022+
return false;
1023+
}
1024+
if (req.method() != io.vertx.core.http.HttpMethod.GET) {
1025+
return false;
1026+
}
1027+
MultiMap headers = req.headers();
1028+
for (String connection : headers.getAll(io.vertx.core.http.HttpHeaders.CONNECTION)) {
1029+
if (connection.toLowerCase().contains(io.vertx.core.http.HttpHeaders.UPGRADE)) {
1030+
for (String upgrade : headers.getAll(io.vertx.core.http.HttpHeaders.UPGRADE)) {
1031+
if (upgrade.toLowerCase().contains(io.vertx.core.http.HttpHeaders.WEBSOCKET)) {
1032+
return true;
1033+
}
1034+
}
1035+
}
1036+
}
1037+
return false;
1038+
}
10191039
}

src/test/java/io/vertx/core/http/Http1xTest.java

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@
4545
import java.util.concurrent.atomic.AtomicBoolean;
4646
import java.util.concurrent.atomic.AtomicInteger;
4747
import java.util.concurrent.atomic.AtomicReference;
48-
import java.util.function.BiConsumer;
49-
import java.util.function.Consumer;
50-
import java.util.function.Function;
51-
import java.util.function.LongConsumer;
48+
import java.util.function.*;
5249
import java.util.stream.Collectors;
5350
import java.util.stream.IntStream;
5451
import java.util.stream.Stream;
@@ -5310,4 +5307,61 @@ public void testMissingHostHeader() throws Exception {
53105307
}));
53115308
await();
53125309
}
5310+
5311+
@Test
5312+
public void testCanUpgradeToWebSocket() throws Exception {
5313+
UnaryOperator<RequestOptions> config = ro -> ro.setMethod(HttpMethod.GET)
5314+
.putHeader(HttpHeaders.CONNECTION, HttpHeaders.UPGRADE)
5315+
.putHeader(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET);
5316+
doTestCanUpgradeToWebSocket(config, true);
5317+
}
5318+
5319+
@Test
5320+
public void testCanUpgradeToWebSocketFirefox() throws Exception {
5321+
UnaryOperator<RequestOptions> config = ro -> ro.setMethod(HttpMethod.GET)
5322+
.putHeader(HttpHeaders.CONNECTION, HttpHeaders.KEEP_ALIVE + ", " + HttpHeaders.UPGRADE)
5323+
.putHeader(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET);
5324+
doTestCanUpgradeToWebSocket(config, true);
5325+
}
5326+
5327+
@Test
5328+
public void testCannotUpgradePostRequestToWebSocket() throws Exception {
5329+
UnaryOperator<RequestOptions> config = ro -> ro.setMethod(HttpMethod.POST)
5330+
.putHeader(HttpHeaders.CONNECTION, HttpHeaders.UPGRADE)
5331+
.putHeader(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET);
5332+
doTestCanUpgradeToWebSocket(config, false);
5333+
}
5334+
5335+
@Test
5336+
public void testCannotUpgradeToWebSocketIfConnectionHeaderIsMissing() throws Exception {
5337+
UnaryOperator<RequestOptions> config = ro -> ro.setMethod(HttpMethod.GET)
5338+
.putHeader(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET);
5339+
doTestCanUpgradeToWebSocket(config, false);
5340+
}
5341+
5342+
@Test
5343+
public void testCannotUpgradeToWebSocketIfUpgradeDoesNotContainWebsocket() throws Exception {
5344+
UnaryOperator<RequestOptions> config = ro -> ro.setMethod(HttpMethod.GET)
5345+
.putHeader(HttpHeaders.CONNECTION, HttpHeaders.UPGRADE)
5346+
.putHeader(HttpHeaders.UPGRADE, "foo");
5347+
doTestCanUpgradeToWebSocket(config, false);
5348+
}
5349+
5350+
private void doTestCanUpgradeToWebSocket(UnaryOperator<RequestOptions> config, boolean shouldSucceed) throws Exception {
5351+
server.requestHandler(req -> {
5352+
HttpServerResponse serverResponse = req.response();
5353+
int statusCode = HttpUtils.canUpgradeToWebSocket(req) ? 200 : 500;
5354+
serverResponse.setStatusCode(statusCode);
5355+
serverResponse.end();
5356+
});
5357+
startServer(testAddress);
5358+
client.request(config.apply(new RequestOptions(requestOptions))).onComplete(onSuccess(req -> {
5359+
req.response().onComplete(onSuccess(resp -> {
5360+
assertEquals(shouldSucceed ? 200 : 500, resp.statusCode());
5361+
testComplete();
5362+
}));
5363+
req.send();
5364+
}));
5365+
await();
5366+
}
53135367
}

0 commit comments

Comments
 (0)