Those who need 'Origin' or 'Sec-WebSocket-Origin' headers should provide them explicitly, like it is stated in WebSocket specs. E.g. through custom headers: HttpHeaders customHeaders = new DefaultHttpHeaders() .add(HttpHeaderNames.ORIGIN, "http://localhost:8080"); new WebSocketClientProtocolHandler( new URI("ws://localhost:1234/test"), WebSocketVersion.V13, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength, handshakeTimeoutMillis) * Remove enforced origin headers. * Update tests Fixes #9673: Origin header is always sent from WebSocket client
This commit is contained in:
parent
f2596fd993
commit
f48d9fa8d0
@ -40,7 +40,6 @@ import io.netty.util.ReferenceCountUtil;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
@ -50,8 +49,6 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
*/
|
||||
public abstract class WebSocketClientHandshaker {
|
||||
|
||||
private static final String HTTP_SCHEME_PREFIX = HttpScheme.HTTP + "://";
|
||||
private static final String HTTPS_SCHEME_PREFIX = HttpScheme.HTTPS + "://";
|
||||
protected static final int DEFAULT_FORCE_CLOSE_TIMEOUT_MILLIS = 10000;
|
||||
|
||||
private final URI uri;
|
||||
@ -576,31 +573,4 @@ public abstract class WebSocketClientHandshaker {
|
||||
// See http://tools.ietf.org/html/rfc6454#section-6.2
|
||||
return NetUtil.toSocketAddressString(host, port);
|
||||
}
|
||||
|
||||
static CharSequence websocketOriginValue(URI wsURL) {
|
||||
String scheme = wsURL.getScheme();
|
||||
final String schemePrefix;
|
||||
int port = wsURL.getPort();
|
||||
final int defaultPort;
|
||||
if (WebSocketScheme.WSS.name().contentEquals(scheme)
|
||||
|| HttpScheme.HTTPS.name().contentEquals(scheme)
|
||||
|| (scheme == null && port == WebSocketScheme.WSS.port())) {
|
||||
|
||||
schemePrefix = HTTPS_SCHEME_PREFIX;
|
||||
defaultPort = WebSocketScheme.WSS.port();
|
||||
} else {
|
||||
schemePrefix = HTTP_SCHEME_PREFIX;
|
||||
defaultPort = WebSocketScheme.WS.port();
|
||||
}
|
||||
|
||||
// Convert uri-host to lower case (by RFC 6454, chapter 4 "Origin of a URI")
|
||||
String host = wsURL.getHost().toLowerCase(Locale.US);
|
||||
|
||||
if (port != defaultPort && port != -1) {
|
||||
// if the port is not standard (80/443) its needed to add the port to the header.
|
||||
// See http://tools.ietf.org/html/rfc6454#section-6.2
|
||||
return schemePrefix + NetUtil.toSocketAddressString(host, port);
|
||||
}
|
||||
return schemePrefix + host;
|
||||
}
|
||||
}
|
||||
|
@ -193,10 +193,6 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY1, key1)
|
||||
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY2, key2);
|
||||
|
||||
if (!headers.contains(HttpHeaderNames.ORIGIN)) {
|
||||
headers.set(HttpHeaderNames.ORIGIN, websocketOriginValue(wsURL));
|
||||
}
|
||||
|
||||
String expectedSubprotocol = expectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) {
|
||||
headers.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
|
@ -187,7 +187,6 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
|
||||
* Upgrade: websocket
|
||||
* Connection: Upgrade
|
||||
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
* Sec-WebSocket-Origin: http://example.com
|
||||
* Sec-WebSocket-Protocol: chat, superchat
|
||||
* Sec-WebSocket-Version: 7
|
||||
* </pre>
|
||||
@ -225,10 +224,6 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
|
||||
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key)
|
||||
.set(HttpHeaderNames.HOST, websocketHostValue(wsURL));
|
||||
|
||||
if (!headers.contains(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN)) {
|
||||
headers.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, websocketOriginValue(wsURL));
|
||||
}
|
||||
|
||||
String expectedSubprotocol = expectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) {
|
||||
headers.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
|
@ -189,7 +189,6 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
* Upgrade: websocket
|
||||
* Connection: Upgrade
|
||||
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
* Sec-WebSocket-Origin: http://example.com
|
||||
* Sec-WebSocket-Protocol: chat, superchat
|
||||
* Sec-WebSocket-Version: 8
|
||||
* </pre>
|
||||
@ -227,10 +226,6 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key)
|
||||
.set(HttpHeaderNames.HOST, websocketHostValue(wsURL));
|
||||
|
||||
if (!headers.contains(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN)) {
|
||||
headers.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, websocketOriginValue(wsURL));
|
||||
}
|
||||
|
||||
String expectedSubprotocol = expectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) {
|
||||
headers.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
|
@ -190,7 +190,6 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
* Upgrade: websocket
|
||||
* Connection: Upgrade
|
||||
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
* Origin: http://example.com
|
||||
* Sec-WebSocket-Protocol: chat, superchat
|
||||
* Sec-WebSocket-Version: 13
|
||||
* </pre>
|
||||
@ -228,10 +227,6 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key)
|
||||
.set(HttpHeaderNames.HOST, websocketHostValue(wsURL));
|
||||
|
||||
if (!headers.contains(HttpHeaderNames.ORIGIN)) {
|
||||
headers.set(HttpHeaderNames.ORIGIN, websocketOriginValue(wsURL));
|
||||
}
|
||||
|
||||
String expectedSubprotocol = expectedSubprotocol();
|
||||
if (expectedSubprotocol != null && !expectedSubprotocol.isEmpty()) {
|
||||
headers.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, expectedSubprotocol);
|
||||
|
@ -109,7 +109,6 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker {
|
||||
* Upgrade: websocket
|
||||
* Connection: Upgrade
|
||||
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
* Sec-WebSocket-Origin: http://example.com
|
||||
* Sec-WebSocket-Protocol: chat, superchat
|
||||
* Sec-WebSocket-Version: 7
|
||||
* </pre>
|
||||
|
@ -116,7 +116,6 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
|
||||
* Upgrade: websocket
|
||||
* Connection: Upgrade
|
||||
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
* Sec-WebSocket-Origin: http://example.com
|
||||
* Sec-WebSocket-Protocol: chat, superchat
|
||||
* Sec-WebSocket-Version: 8
|
||||
* </pre>
|
||||
|
@ -115,7 +115,6 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
||||
* Upgrade: websocket
|
||||
* Connection: Upgrade
|
||||
* Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
|
||||
* Origin: http://example.com
|
||||
* Sec-WebSocket-Protocol: chat, superchat
|
||||
* Sec-WebSocket-Version: 13
|
||||
* </pre>
|
||||
|
@ -31,20 +31,28 @@ import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||
import io.netty.handler.codec.http.HttpRequestEncoder;
|
||||
import io.netty.handler.codec.http.HttpResponseDecoder;
|
||||
import io.netty.handler.codec.http.HttpScheme;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.NetUtil;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public abstract class WebSocketClientHandshakerTest {
|
||||
private static final String HTTP_SCHEME_PREFIX = HttpScheme.HTTP + "://";
|
||||
private static final String HTTPS_SCHEME_PREFIX = HttpScheme.HTTPS + "://";
|
||||
|
||||
protected abstract WebSocketClientHandshaker newHandshaker(URI uri, String subprotocol, HttpHeaders headers,
|
||||
boolean absoluteUpgradeUrl);
|
||||
|
||||
protected WebSocketClientHandshaker newHandshaker(URI uri) {
|
||||
return newHandshaker(uri, null, null, false);
|
||||
HttpHeaders headers = new DefaultHttpHeaders()
|
||||
.add(getOriginHeaderName(), websocketOriginValue(uri));
|
||||
return newHandshaker(uri, null, headers, false);
|
||||
}
|
||||
|
||||
protected abstract CharSequence getOriginHeaderName();
|
||||
@ -361,4 +369,31 @@ public abstract class WebSocketClientHandshakerTest {
|
||||
|
||||
request.release();
|
||||
}
|
||||
|
||||
static CharSequence websocketOriginValue(URI wsURL) {
|
||||
String scheme = wsURL.getScheme();
|
||||
final String schemePrefix;
|
||||
int port = wsURL.getPort();
|
||||
final int defaultPort;
|
||||
if (WebSocketScheme.WSS.name().contentEquals(scheme)
|
||||
|| HttpScheme.HTTPS.name().contentEquals(scheme)
|
||||
|| (scheme == null && port == WebSocketScheme.WSS.port())) {
|
||||
|
||||
schemePrefix = HTTPS_SCHEME_PREFIX;
|
||||
defaultPort = WebSocketScheme.WSS.port();
|
||||
} else {
|
||||
schemePrefix = HTTP_SCHEME_PREFIX;
|
||||
defaultPort = WebSocketScheme.WS.port();
|
||||
}
|
||||
|
||||
// Convert uri-host to lower case (by RFC 6454, chapter 4 "Origin of a URI")
|
||||
String host = wsURL.getHost().toLowerCase(Locale.US);
|
||||
|
||||
if (port != defaultPort && port != -1) {
|
||||
// if the port is not standard (80/443) its needed to add the port to the header.
|
||||
// See http://tools.ietf.org/html/rfc6454#section-6.2
|
||||
return schemePrefix + NetUtil.toSocketAddressString(host, port);
|
||||
}
|
||||
return schemePrefix + host;
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public class WebSocketHandshakeHandOverTest {
|
||||
assertTrue(serverReceivedHandshake);
|
||||
assertNotNull(serverHandshakeComplete);
|
||||
assertEquals("/test", serverHandshakeComplete.requestUri());
|
||||
assertEquals(8, serverHandshakeComplete.requestHeaders().size());
|
||||
assertEquals(7, serverHandshakeComplete.requestHeaders().size());
|
||||
assertEquals("test-proto-2", serverHandshakeComplete.selectedSubprotocol());
|
||||
|
||||
// Transfer the handshake response and the websocket message to the client
|
||||
|
Loading…
x
Reference in New Issue
Block a user