Skip to content

Commit af134bb

Browse files
authored
Filter out Host header when proxying websockets (#134)
1 parent 7674c5a commit af134bb

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

src/main/java/io/vertx/httpproxy/impl/ReverseProxy.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.*;
2929

3030
import static io.vertx.core.http.HttpHeaders.CONNECTION;
31+
import static io.vertx.core.http.HttpHeaders.HOST;
3132
import static io.vertx.core.http.HttpHeaders.UPGRADE;
3233

3334
public class ReverseProxy implements HttpProxy {
@@ -175,11 +176,18 @@ public Future<ProxyResponse> sendRequest() {
175176
return resolveOrigin(this).compose(request -> {
176177
request.setMethod(request().getMethod());
177178
request.setURI(request().getURI());
178-
// Firefox is known to send an unexpected connection header value
179-
// Connection=keep-alive, Upgrade
180-
// It leads to a failure in websocket proxying
181-
// So we make sure the standard value is sent to the backend
182-
request.headers().addAll(request().headers()).set(CONNECTION, UPGRADE);
179+
for (Map.Entry<String, String> header : request().headers()) {
180+
String name = header.getKey();
181+
if (name.equalsIgnoreCase(CONNECTION.toString())) {
182+
// Firefox is known to send an unexpected connection header value
183+
// Connection=keep-alive, Upgrade
184+
// It leads to a failure in websocket proxying
185+
// So we make sure the standard value is sent to the backend
186+
request.headers().set(CONNECTION, UPGRADE);
187+
} else if (!name.equalsIgnoreCase(HOST.toString())) {
188+
request.headers().add(name, header.getValue());
189+
}
190+
}
183191
Future<HttpClientResponse> responseFuture = request.connect();
184192
ReadStream<Buffer> readStream = request().getBody().stream();
185193
readStream.handler(request::write);

src/test/java/io/vertx/tests/WebSocketTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,37 @@ public void testWebSocketFirefox(TestContext ctx) {
155155
}));
156156
}
157157

158+
@Test
159+
public void testWebSocketHostHeader(TestContext ctx) {
160+
Async async = ctx.async();
161+
SocketAddress backend = startHttpBackend(ctx, 8081, req -> {
162+
ctx.assertEquals("localhost:8081", req.headers().get("Host"));
163+
Future<ServerWebSocket> fut = req.toWebSocket();
164+
fut.onComplete(ctx.asyncAssertSuccess(ws -> {
165+
ws.closeHandler(v -> {
166+
async.complete();
167+
});
168+
}));
169+
});
170+
startProxy(backend);
171+
httpClient = vertx.createHttpClient();
172+
RequestOptions options = new RequestOptions()
173+
.setPort(8080)
174+
.setHost("localhost")
175+
.setURI("/ws")
176+
.putHeader("Origin", "http://localhost:8080")
177+
.putHeader("Connection", "Upgrade")
178+
.putHeader("Upgrade", "Websocket")
179+
.putHeader("Sec-WebSocket-Version", "13")
180+
.putHeader("Sec-WebSocket-Key", "xy6UoM3l3TcREmAeAhZuYQ==");
181+
httpClient.request(options).onComplete(ctx.asyncAssertSuccess(clientRequest -> {
182+
clientRequest.connect().onComplete(ctx.asyncAssertSuccess(response -> {
183+
ctx.assertEquals(101, response.statusCode());
184+
response.netSocket().close();
185+
}));
186+
}));
187+
}
188+
158189
@Test
159190
public void testVariableFromInterceptor(TestContext ctx) {
160191
Async async = ctx.async();

0 commit comments

Comments
 (0)