diff --git a/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java b/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java index 77848b6..cda186f 100644 --- a/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java +++ b/src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java @@ -28,6 +28,7 @@ import java.util.*; import static io.vertx.core.http.HttpHeaders.CONNECTION; +import static io.vertx.core.http.HttpHeaders.HOST; import static io.vertx.core.http.HttpHeaders.UPGRADE; public class ReverseProxy implements HttpProxy { @@ -175,11 +176,18 @@ public Future sendRequest() { return resolveOrigin(this).compose(request -> { request.setMethod(request().getMethod()); request.setURI(request().getURI()); - // Firefox is known to send an unexpected connection header value - // Connection=keep-alive, Upgrade - // It leads to a failure in websocket proxying - // So we make sure the standard value is sent to the backend - request.headers().addAll(request().headers()).set(CONNECTION, UPGRADE); + for (Map.Entry header : request().headers()) { + String name = header.getKey(); + if (name.equalsIgnoreCase(CONNECTION.toString())) { + // Firefox is known to send an unexpected connection header value + // Connection=keep-alive, Upgrade + // It leads to a failure in websocket proxying + // So we make sure the standard value is sent to the backend + request.headers().set(CONNECTION, UPGRADE); + } else if (!name.equalsIgnoreCase(HOST.toString())) { + request.headers().add(name, header.getValue()); + } + } Future responseFuture = request.connect(); ReadStream readStream = request().getBody().stream(); readStream.handler(request::write); diff --git a/src/test/java/io/vertx/tests/WebSocketTest.java b/src/test/java/io/vertx/tests/WebSocketTest.java index 6471468..1f2b139 100644 --- a/src/test/java/io/vertx/tests/WebSocketTest.java +++ b/src/test/java/io/vertx/tests/WebSocketTest.java @@ -155,6 +155,37 @@ public void testWebSocketFirefox(TestContext ctx) { })); } + @Test + public void testWebSocketHostHeader(TestContext ctx) { + Async async = ctx.async(); + SocketAddress backend = startHttpBackend(ctx, 8081, req -> { + ctx.assertEquals("localhost:8081", req.headers().get("Host")); + Future fut = req.toWebSocket(); + fut.onComplete(ctx.asyncAssertSuccess(ws -> { + ws.closeHandler(v -> { + async.complete(); + }); + })); + }); + startProxy(backend); + httpClient = vertx.createHttpClient(); + RequestOptions options = new RequestOptions() + .setPort(8080) + .setHost("localhost") + .setURI("/ws") + .putHeader("Origin", "http://localhost:8080") + .putHeader("Connection", "Upgrade") + .putHeader("Upgrade", "Websocket") + .putHeader("Sec-WebSocket-Version", "13") + .putHeader("Sec-WebSocket-Key", "xy6UoM3l3TcREmAeAhZuYQ=="); + httpClient.request(options).onComplete(ctx.asyncAssertSuccess(clientRequest -> { + clientRequest.connect().onComplete(ctx.asyncAssertSuccess(response -> { + ctx.assertEquals(101, response.statusCode()); + response.netSocket().close(); + })); + })); + } + @Test public void testVariableFromInterceptor(TestContext ctx) { Async async = ctx.async();