Merge pull request #6411 from eclipse/jetty-10.0.x-6407-ClientUpgradeRequestUri

Issue #6407 - Fix URI validation for WebSocket ClientUpgradeRequest
This commit is contained in:
Lachlan 2021-06-23 10:37:58 +10:00 committed by GitHub
commit 1cd0093855
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 38 deletions

View File

@ -88,25 +88,17 @@ public abstract class CoreClientUpgradeRequest extends HttpRequest implements Re
// Validate websocket URI // Validate websocket URI
if (!requestURI.isAbsolute()) if (!requestURI.isAbsolute())
{
throw new IllegalArgumentException("WebSocket URI must be absolute"); throw new IllegalArgumentException("WebSocket URI must be absolute");
}
if (StringUtil.isBlank(requestURI.getScheme())) if (StringUtil.isBlank(requestURI.getScheme()))
{
throw new IllegalArgumentException("WebSocket URI must include a scheme"); throw new IllegalArgumentException("WebSocket URI must include a scheme");
}
String scheme = requestURI.getScheme(); String scheme = requestURI.getScheme();
if (!HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme)) if (!HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme))
{
throw new IllegalArgumentException("WebSocket URI scheme only supports [ws] and [wss], not [" + scheme + "]"); throw new IllegalArgumentException("WebSocket URI scheme only supports [ws] and [wss], not [" + scheme + "]");
}
if (requestURI.getHost() == null) if (requestURI.getHost() == null)
{
throw new IllegalArgumentException("Invalid WebSocket URI: host not present"); throw new IllegalArgumentException("Invalid WebSocket URI: host not present");
}
this.wsClient = webSocketClient; this.wsClient = webSocketClient;
this.futureCoreSession = new CompletableFuture<>(); this.futureCoreSession = new CompletableFuture<>();
@ -437,7 +429,7 @@ public abstract class CoreClientUpgradeRequest extends HttpRequest implements Re
Negotiated negotiated = new Negotiated( Negotiated negotiated = new Negotiated(
request.getURI(), request.getURI(),
negotiatedSubProtocol, negotiatedSubProtocol,
HttpScheme.HTTPS.is(request.getScheme()), // TODO better than this? HttpClient.isSchemeSecure(request.getScheme()),
extensionStack, extensionStack,
WebSocketConstants.SPEC_VERSION_STRING); WebSocketConstants.SPEC_VERSION_STRING);

View File

@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.UrlEncoded; import org.eclipse.jetty.util.UrlEncoded;
@ -134,24 +135,14 @@ public class Negotiated
String httpScheme = uri.getScheme(); String httpScheme = uri.getScheme();
if (httpScheme == null) if (httpScheme == null)
return uri; return uri;
if (HttpScheme.WS.is(httpScheme) || HttpScheme.WSS.is(httpScheme))
if ("ws".equalsIgnoreCase(httpScheme) || "wss".equalsIgnoreCase(httpScheme))
{
// keep as-is
return uri; return uri;
}
if ("http".equalsIgnoreCase(httpScheme)) String afterScheme = uri.toString().substring(httpScheme.length());
{ if (HttpScheme.HTTP.is(httpScheme))
// convert to ws return new URI("ws" + afterScheme);
return new URI("ws" + uri.toString().substring(httpScheme.length())); if (HttpScheme.HTTPS.is(httpScheme))
} return new URI("wss" + afterScheme);
if ("https".equalsIgnoreCase(httpScheme))
{
// convert to wss
return new URI("wss" + uri.toString().substring(httpScheme.length()));
}
throw new URISyntaxException(uri.toString(), "Unrecognized HTTP scheme"); throw new URISyntaxException(uri.toString(), "Unrecognized HTTP scheme");
} }

View File

@ -103,23 +103,17 @@ public final class WSURI
{ {
Objects.requireNonNull(inputUri, "Input URI must not be null"); Objects.requireNonNull(inputUri, "Input URI must not be null");
String httpScheme = inputUri.getScheme(); String httpScheme = inputUri.getScheme();
if (httpScheme == null)
throw new URISyntaxException(inputUri.toString(), "Undefined HTTP scheme");
if ("ws".equalsIgnoreCase(httpScheme) || "wss".equalsIgnoreCase(httpScheme)) if ("ws".equalsIgnoreCase(httpScheme) || "wss".equalsIgnoreCase(httpScheme))
{
// keep as-is
return inputUri; return inputUri;
}
String afterScheme = inputUri.toString().substring(httpScheme.length());
if ("http".equalsIgnoreCase(httpScheme)) if ("http".equalsIgnoreCase(httpScheme))
{ return new URI("ws" + afterScheme);
// convert to ws
return new URI("ws" + inputUri.toString().substring(httpScheme.length()));
}
if ("https".equalsIgnoreCase(httpScheme)) if ("https".equalsIgnoreCase(httpScheme))
{ return new URI("wss" + afterScheme);
// convert to wss
return new URI("wss" + inputUri.toString().substring(httpScheme.length()));
}
throw new URISyntaxException(inputUri.toString(), "Unrecognized HTTP scheme"); throw new URISyntaxException(inputUri.toString(), "Unrecognized HTTP scheme");
} }

View File

@ -50,11 +50,15 @@ public final class ClientUpgradeRequest implements UpgradeRequest
this.host = null; this.host = null;
} }
/**
* @deprecated use {@link #ClientUpgradeRequest()} instead.
*/
@Deprecated
public ClientUpgradeRequest(URI uri) public ClientUpgradeRequest(URI uri)
{ {
this.requestURI = uri; this.requestURI = uri;
String scheme = uri.getScheme(); String scheme = uri.getScheme();
if (!HttpScheme.WS.is(scheme) || !HttpScheme.WSS.is(scheme)) if (!HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme))
throw new IllegalArgumentException("URI scheme must be 'ws' or 'wss'"); throw new IllegalArgumentException("URI scheme must be 'ws' or 'wss'");
this.host = this.requestURI.getHost(); this.host = this.requestURI.getHost();
} }