Override Sec-WebSocket-Protocol websocket handshake response header after custom headers to avoid duplication (#10793)
Motivation: According rfc (https://tools.ietf.org/html/rfc6455#section-11.3.4), `Sec-WebSocket-Protocol` header field MUST NOT appear more than once in an HTTP response. At the moment we can pass `Sec-WebSocket-Protocol` via custom headers and it will be added to response. Modification: Change method add() to set() for avoid duplication. If we pass sub protocols in handshaker constructor it means that they are preferred over custom ones. Result: Less error prone behavior.
This commit is contained in:
parent
3354c7b0bf
commit
f40b4f15a6
@ -165,7 +165,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.headers().add(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
|
|
||||||
String protocol = req.headers().get(HttpHeaderNames.WEBSOCKET_PROTOCOL);
|
String protocol = req.headers().get(HttpHeaderNames.WEBSOCKET_PROTOCOL);
|
||||||
if (protocol != null) {
|
if (protocol != null) {
|
||||||
res.headers().add(HttpHeaderNames.WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
res.headers().set(HttpHeaderNames.WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -161,7 +161,7 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker {
|
|||||||
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.headers().add(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -167,7 +167,7 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
|
|||||||
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.headers().add(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -165,7 +165,7 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
|||||||
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.headers().add(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -48,12 +48,15 @@ public abstract class WebSocketServerHandshakerTest {
|
|||||||
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ==")
|
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY, "dGhlIHNhbXBsZSBub25jZQ==")
|
||||||
.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, "http://example.com")
|
.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, "http://example.com")
|
||||||
.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, "chat, superchat")
|
.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, "chat, superchat")
|
||||||
|
.set(HttpHeaderNames.WEBSOCKET_PROTOCOL, "chat, superchat")
|
||||||
.set(HttpHeaderNames.SEC_WEBSOCKET_VERSION, webSocketVersion().toAsciiString());
|
.set(HttpHeaderNames.SEC_WEBSOCKET_VERSION, webSocketVersion().toAsciiString());
|
||||||
HttpHeaders customResponseHeaders = new DefaultHttpHeaders();
|
HttpHeaders customResponseHeaders = new DefaultHttpHeaders();
|
||||||
// set duplicate required headers and one custom
|
// set duplicate required headers and one custom
|
||||||
customResponseHeaders
|
customResponseHeaders
|
||||||
.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
|
.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
|
||||||
.set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
|
.set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
|
||||||
|
.set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, "superchat")
|
||||||
|
.set(HttpHeaderNames.WEBSOCKET_PROTOCOL, "superchat")
|
||||||
.set("custom", "header");
|
.set("custom", "header");
|
||||||
|
|
||||||
if (webSocketVersion() != WebSocketVersion.V00) {
|
if (webSocketVersion() != WebSocketVersion.V00) {
|
||||||
@ -68,8 +71,14 @@ public abstract class WebSocketServerHandshakerTest {
|
|||||||
assertEquals(1, responseHeaders.getAll(HttpHeaderNames.CONNECTION).size());
|
assertEquals(1, responseHeaders.getAll(HttpHeaderNames.CONNECTION).size());
|
||||||
assertEquals(1, responseHeaders.getAll(HttpHeaderNames.UPGRADE).size());
|
assertEquals(1, responseHeaders.getAll(HttpHeaderNames.UPGRADE).size());
|
||||||
assertTrue(responseHeaders.containsValue("custom", "header", true));
|
assertTrue(responseHeaders.containsValue("custom", "header", true));
|
||||||
|
|
||||||
if (webSocketVersion() != WebSocketVersion.V00) {
|
if (webSocketVersion() != WebSocketVersion.V00) {
|
||||||
assertFalse(responseHeaders.containsValue(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, "12345", false));
|
assertFalse(responseHeaders.containsValue(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, "12345", false));
|
||||||
|
assertEquals(1, responseHeaders.getAll(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL).size());
|
||||||
|
assertEquals("chat", responseHeaders.get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL));
|
||||||
|
} else {
|
||||||
|
assertEquals(1, responseHeaders.getAll(HttpHeaderNames.WEBSOCKET_PROTOCOL).size());
|
||||||
|
assertEquals("chat", responseHeaders.get(HttpHeaderNames.WEBSOCKET_PROTOCOL));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
request.release();
|
request.release();
|
||||||
|
Loading…
Reference in New Issue
Block a user