diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java index a2fce7c911..91b963271e 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07.java @@ -218,12 +218,19 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker { if (customHeaders != null) { headers.add(customHeaders); + if (!headers.contains(HttpHeaderNames.HOST)) { + // Only add HOST header if customHeaders did not contain it. + // + // See https://github.com/netty/netty/issues/10101 + headers.set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); + } + } else { + headers.set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); } headers.set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET) .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE) - .set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key) - .set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); + .set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key); if (!headers.contains(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN)) { headers.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, websocketOriginValue(wsURL)); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java index 245eff8753..76cf9c1874 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker08.java @@ -220,12 +220,19 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker { if (customHeaders != null) { headers.add(customHeaders); + if (!headers.contains(HttpHeaderNames.HOST)) { + // Only add HOST header if customHeaders did not contain it. + // + // See https://github.com/netty/netty/issues/10101 + headers.set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); + } + } else { + headers.set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); } headers.set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET) .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE) - .set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key) - .set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); + .set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key); if (!headers.contains(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN)) { headers.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, websocketOriginValue(wsURL)); diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java index 8efbb4a2e5..82f90b4c8d 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker13.java @@ -221,12 +221,19 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker { if (customHeaders != null) { headers.add(customHeaders); + if (!headers.contains(HttpHeaderNames.HOST)) { + // Only add HOST header if customHeaders did not contain it. + // + // See https://github.com/netty/netty/issues/10101 + headers.set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); + } + } else { + headers.set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); } headers.set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET) .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE) - .set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key) - .set(HttpHeaderNames.HOST, websocketHostValue(wsURL)); + .set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key); if (!headers.contains(HttpHeaderNames.ORIGIN)) { headers.set(HttpHeaderNames.ORIGIN, websocketOriginValue(wsURL)); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07Test.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07Test.java index 4d9be6cb67..dea8b94992 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07Test.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshaker07Test.java @@ -15,12 +15,33 @@ */ package io.netty.handler.codec.http.websocketx; +import io.netty.handler.codec.http.DefaultHttpHeaders; +import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaders; +import org.junit.Test; import java.net.URI; +import static org.junit.Assert.assertEquals; + public class WebSocketClientHandshaker07Test extends WebSocketClientHandshakerTest { + + @Test + public void testHostHeaderPreserved() { + URI uri = URI.create("ws://localhost:9999"); + WebSocketClientHandshaker handshaker = newHandshaker(uri, null, + new DefaultHttpHeaders().set(HttpHeaderNames.HOST, "test.netty.io"), false); + + FullHttpRequest request = handshaker.newHandshakeRequest(); + try { + assertEquals("/", request.uri()); + assertEquals("test.netty.io", request.headers().get(HttpHeaderNames.HOST)); + } finally { + request.release(); + } + } + @Override protected WebSocketClientHandshaker newHandshaker(URI uri, String subprotocol, HttpHeaders headers, boolean absoluteUpgradeUrl) { diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerTest.java index 327439d678..3abf013c61 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/websocketx/WebSocketClientHandshakerTest.java @@ -364,7 +364,9 @@ public abstract class WebSocketClientHandshakerTest { // add values for the headers that are reserved for use in the websockets handshake for (CharSequence header : getHandshakeRequiredHeaderNames()) { - inputHeaders.add(header, bogusHeaderValue); + if (!HttpHeaderNames.HOST.equals(header)) { + inputHeaders.add(header, bogusHeaderValue); + } } inputHeaders.add(getProtocolHeaderName(), bogusSubProtocol);