[#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;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
@ -1671,6 +1672,48 @@ public abstract class HttpHeaders implements Iterable<Map.Entry<String, String>>
|
||||
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.
|
||||
*
|
||||
|
@ -196,10 +196,9 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
+ upgrade);
|
||||
}
|
||||
|
||||
String connection = headers.get(Names.CONNECTION);
|
||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
||||
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||
+ connection);
|
||||
+ headers.get(Names.CONNECTION));
|
||||
}
|
||||
|
||||
ByteBuf challenge = response.content();
|
||||
|
@ -170,9 +170,9 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response upgrade: " + upgrade);
|
||||
}
|
||||
|
||||
String connection = headers.get(Names.CONNECTION);
|
||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
|
||||
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||
+ headers.get(Names.CONNECTION));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
String connection = headers.get(Names.CONNECTION);
|
||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
|
||||
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||
+ headers.get(Names.CONNECTION));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
String connection = headers.get(Names.CONNECTION);
|
||||
if (!Values.UPGRADE.equalsIgnoreCase(connection)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: " + connection);
|
||||
if (!headers.containsValue(Names.CONNECTION, Values.UPGRADE, true)) {
|
||||
throw new WebSocketHandshakeException("Invalid handshake response connection: "
|
||||
+ headers.get(Names.CONNECTION));
|
||||
}
|
||||
|
||||
String accept = headers.get(Names.SEC_WEBSOCKET_ACCEPT);
|
||||
|
@ -109,7 +109,7 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
||||
protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
|
||||
|
||||
// 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))) {
|
||||
throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user