[#4754] Correctly detect websocket upgrade
Motivation: If the Connection header contains multiple values (which is valid) we fail to detect a websocket upgrade Modification: - Add new method which allows to check if a header field contains a specific value (and also respect multiple header values) - Use this method to detect handshake Result: Correct detect handshake if Connection header contains multiple values (seperated by ',').
This commit is contained in:
parent
d0b0e028d0
commit
d5a8b65700
@ -16,6 +16,7 @@
|
|||||||
package io.netty.handler.codec.http;
|
package io.netty.handler.codec.http;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
@ -1671,6 +1672,48 @@ public abstract class HttpHeaders implements Iterable<Map.Entry<String, String>>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if a header with the {@code name} and {@code value} exists, {@code false} otherwise.
|
||||||
|
* This also handles multiple values that are seperated with a {@code ,}.
|
||||||
|
* <p>
|
||||||
|
* If {@code ignoreCase} is {@code true} then a case insensitive compare is done on the value.
|
||||||
|
* @param name the name of the header to find
|
||||||
|
* @param value the value of the header to find
|
||||||
|
* @param ignoreCase {@code true} then a case insensitive compare is run to compare values.
|
||||||
|
* otherwise a case sensitive compare is run to compare values.
|
||||||
|
*/
|
||||||
|
public boolean containsValue(CharSequence name, CharSequence value, boolean ignoreCase) {
|
||||||
|
List<String> values = getAll(name);
|
||||||
|
if (values.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String v: values) {
|
||||||
|
if (contains(v, value, ignoreCase)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean contains(String value, CharSequence expected, boolean ignoreCase) {
|
||||||
|
String[] parts = StringUtil.split(value, ',');
|
||||||
|
if (ignoreCase) {
|
||||||
|
for (String s: parts) {
|
||||||
|
if (equalsIgnoreCase(expected, s.trim())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (String s: parts) {
|
||||||
|
if (s.trim().contentEquals(expected)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if a header with the name and value exists.
|
* Returns {@code true} if a header with the name and value exists.
|
||||||
*
|
*
|
||||||
|
@ -196,10 +196,9 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
|||||||
+ upgrade);
|
+ upgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
String connection = headers.get(Names.CONNECTION);
|
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
|
||||||
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||||
+ connection);
|
+ headers.get(Names.CONNECTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf challenge = response.content();
|
ByteBuf challenge = response.content();
|
||||||
|
@ -170,9 +170,9 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
|
|||||||
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
String connection = headers.get(Names.CONNECTION);
|
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||||
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
|
+ headers.get(Names.CONNECTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
||||||
|
@ -170,9 +170,9 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
|||||||
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
String connection = headers.get(Names.CONNECTION);
|
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||||
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
|
+ headers.get(Names.CONNECTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
||||||
|
@ -180,9 +180,9 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
|||||||
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
||||||
}
|
}
|
||||||
|
|
||||||
String connection = headers.get(Names.CONNECTION);
|
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||||
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
|
+ headers.get(Names.CONNECTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
||||||
|
@ -109,7 +109,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
|||||||
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
|
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
|
||||||
|
|
||||||
// Serve the WebSocket handshake request.
|
// Serve the WebSocket handshake request.
|
||||||
if (!Values.UPGRADE.equalsIgnoreCase(req.headers().get(CONNECTION))
|
if (!req.headers().containsValue(CONNECTION, Values.UPGRADE, true)
|
||||||
|| !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) {
|
|| !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) {
|
||||||
throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
|
throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user