* Issue #11414 - use HttpURI instead of URIUtil to have a single point of spec behavior * Issue #11414 - enforce lowercase scheme in HttpConfiguration.secureScheme * Issue #11414 - Scheme produced on `Location` header is lowercase * Issue #11414 - Scheme to lowercase * Issue #11414 - Scheme to lowercase * Revert change to HttpClient * Added schema port knowledge to URIUtil * Fixed tests for normalized URIs * updates from review * updates from review * Fix tests * Restored methods as deprecated * More testing --------- Co-authored-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
d02406c164
commit
f07d812698
|
@ -56,6 +56,7 @@ import org.eclipse.jetty.util.Jetty;
|
|||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.SocketAddressResolver;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
@ -1099,11 +1100,17 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return proxyConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a normalized port suitable for use by Origin and Address
|
||||
* @param scheme the scheme to use for the default port (if port is unspecified)
|
||||
* @param port the port (0 or negative means the port is unspecified)
|
||||
* @return the normalized port.
|
||||
*/
|
||||
public static int normalizePort(String scheme, int port)
|
||||
{
|
||||
if (port > 0)
|
||||
return port;
|
||||
return HttpScheme.getDefaultPort(scheme);
|
||||
return URIUtil.getDefaultPortForScheme(scheme);
|
||||
}
|
||||
|
||||
public ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory)
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -278,7 +279,7 @@ public class HttpRedirector
|
|||
Matcher matcher = URI_PATTERN.matcher(location);
|
||||
if (matcher.matches())
|
||||
{
|
||||
String scheme = matcher.group(2);
|
||||
String scheme = URIUtil.normalizeScheme(matcher.group(2));
|
||||
String authority = matcher.group(3);
|
||||
String path = matcher.group(4);
|
||||
String query = matcher.group(5);
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.HostPort;
|
||||
|
@ -74,7 +75,7 @@ public class Origin
|
|||
|
||||
public Origin(String scheme, Address address, Object tag, Protocol protocol)
|
||||
{
|
||||
this.scheme = Objects.requireNonNull(scheme);
|
||||
this.scheme = URIUtil.normalizeScheme(Objects.requireNonNull(scheme));
|
||||
this.address = address;
|
||||
this.tag = tag;
|
||||
this.protocol = protocol;
|
||||
|
@ -122,9 +123,7 @@ public class Origin
|
|||
|
||||
public String asString()
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
URIUtil.appendSchemeHostPort(result, scheme, address.host, address.port);
|
||||
return result.toString();
|
||||
return HttpURI.from(scheme, address.host, address.port, null).asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.eclipse.jetty.util.Callback;
|
|||
import org.eclipse.jetty.util.HostPort;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
@ -80,7 +81,8 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
|
||||
String host = HostPort.normalizeHost(getHost());
|
||||
int port = getPort();
|
||||
if (port != HttpScheme.getDefaultPort(getScheme()))
|
||||
String scheme = getScheme();
|
||||
if (port != URIUtil.getDefaultPortForScheme(scheme))
|
||||
host += ":" + port;
|
||||
hostField = new HttpField(HttpHeader.HOST, host);
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.eclipse.jetty.http.HttpField;
|
|||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
|
@ -122,9 +123,7 @@ public class HttpRequest implements Request
|
|||
{
|
||||
if (newURI == null)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(64);
|
||||
URIUtil.appendSchemeHostPort(builder, getScheme(), getHost(), getPort());
|
||||
newURI = URI.create(builder.toString());
|
||||
newURI = HttpURI.from(getScheme(), getHost(), getPort(), null).toURI();
|
||||
}
|
||||
|
||||
HttpRequest newRequest = copyInstance(newURI);
|
||||
|
@ -184,7 +183,7 @@ public class HttpRequest implements Request
|
|||
@Override
|
||||
public Request scheme(String scheme)
|
||||
{
|
||||
this.scheme = scheme;
|
||||
this.scheme = URIUtil.normalizeScheme(scheme);
|
||||
this.uri = null;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -32,13 +32,13 @@ import org.eclipse.jetty.http.HttpField;
|
|||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.UriCompliance;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.toolchain.test.Net;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
@ -68,9 +68,8 @@ public class HttpClientURITest extends AbstractHttpClientServerTest
|
|||
.timeout(5, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(host, request.getHost());
|
||||
StringBuilder uri = new StringBuilder();
|
||||
URIUtil.appendSchemeHostPort(uri, scenario.getScheme(), host, connector.getLocalPort());
|
||||
assertEquals(uri.toString(), request.getURI().toString());
|
||||
HttpURI httpURI = HttpURI.from(scenario.getScheme(), host, connector.getLocalPort(), null);
|
||||
assertEquals(httpURI.asString(), request.getURI().toString());
|
||||
|
||||
assertEquals(HttpStatus.OK_200, request.send().getStatus());
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Properties;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
|
@ -249,9 +250,7 @@ public class XmlConfiguredJetty
|
|||
|
||||
public URI getServerURI() throws UnknownHostException
|
||||
{
|
||||
StringBuilder uri = new StringBuilder();
|
||||
URIUtil.appendSchemeHostPort(uri, getScheme(), InetAddress.getLocalHost().getHostAddress(), getServerPort());
|
||||
return URI.create(uri.toString());
|
||||
return HttpURI.from(getScheme(), InetAddress.getLocalHost().getHostAddress(), getServerPort(), null).toURI();
|
||||
}
|
||||
|
||||
public Path getJettyBasePath()
|
||||
|
@ -332,7 +331,7 @@ public class XmlConfiguredJetty
|
|||
|
||||
public void setScheme(String scheme)
|
||||
{
|
||||
this._scheme = scheme;
|
||||
this._scheme = URIUtil.normalizeScheme(scheme);
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.eclipse.jetty.server.Request;
|
|||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.handler.TryPathsHandler;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -317,7 +318,7 @@ public class FastCGIProxyHandler extends ProxyHandler.Reverse
|
|||
// If the Host header is missing, add it.
|
||||
if (!proxyToServerRequest.getHeaders().contains(HttpHeader.HOST))
|
||||
{
|
||||
if (serverPort != HttpScheme.getDefaultPort(scheme))
|
||||
if (serverPort != URIUtil.getDefaultPortForScheme(scheme))
|
||||
serverName += ":" + serverPort;
|
||||
String host = serverName;
|
||||
proxyToServerRequest.headers(headers -> headers
|
||||
|
|
|
@ -17,16 +17,17 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Index;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
/**
|
||||
* HTTP and WebSocket Schemes
|
||||
*/
|
||||
public enum HttpScheme
|
||||
{
|
||||
HTTP("http", 80),
|
||||
HTTPS("https", 443),
|
||||
WS("ws", 80),
|
||||
WSS("wss", 443);
|
||||
HTTP("http"),
|
||||
HTTPS("https"),
|
||||
WS("ws"),
|
||||
WSS("wss");
|
||||
|
||||
public static final Index<HttpScheme> CACHE = new Index.Builder<HttpScheme>()
|
||||
.caseSensitive(false)
|
||||
|
@ -37,11 +38,11 @@ public enum HttpScheme
|
|||
private final ByteBuffer _buffer;
|
||||
private final int _defaultPort;
|
||||
|
||||
HttpScheme(String s, int port)
|
||||
HttpScheme(String s)
|
||||
{
|
||||
_string = s;
|
||||
_buffer = BufferUtil.toBuffer(s);
|
||||
_defaultPort = port;
|
||||
_defaultPort = URIUtil.getDefaultPortForScheme(s);
|
||||
}
|
||||
|
||||
public ByteBuffer asByteBuffer()
|
||||
|
@ -75,16 +76,29 @@ public enum HttpScheme
|
|||
return _string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default port for a URI scheme
|
||||
* @param scheme The scheme
|
||||
* @return Default port for URI scheme
|
||||
* @deprecated Use {@link URIUtil#getDefaultPortForScheme(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static int getDefaultPort(String scheme)
|
||||
{
|
||||
HttpScheme httpScheme = scheme == null ? null : CACHE.get(scheme);
|
||||
return httpScheme == null ? HTTP.getDefaultPort() : httpScheme.getDefaultPort();
|
||||
return URIUtil.getDefaultPortForScheme(scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a port for a URI scheme
|
||||
* @param scheme the scheme
|
||||
* @param port the port to normalize
|
||||
* @return The normalized port
|
||||
* @deprecated Use {@link URIUtil#normalizePortForScheme(String, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static int normalizePort(String scheme, int port)
|
||||
{
|
||||
HttpScheme httpScheme = scheme == null ? null : CACHE.get(scheme);
|
||||
return httpScheme == null ? port : httpScheme.normalizePort(port);
|
||||
return URIUtil.normalizePortForScheme(scheme, port);
|
||||
}
|
||||
|
||||
public static boolean isSecure(String scheme)
|
||||
|
|
|
@ -151,6 +151,11 @@ public interface HttpURI
|
|||
return new Mutable(scheme, host, port, pathQuery).asImmutable();
|
||||
}
|
||||
|
||||
static Immutable from(String scheme, String host, int port, String path, String query, String fragment)
|
||||
{
|
||||
return new Immutable(scheme, host, port, path, query, fragment);
|
||||
}
|
||||
|
||||
Immutable asImmutable();
|
||||
|
||||
String asString();
|
||||
|
@ -302,18 +307,19 @@ public interface HttpURI
|
|||
_violations = Collections.unmodifiableSet(EnumSet.copyOf(builder._violations));
|
||||
}
|
||||
|
||||
private Immutable(String uri)
|
||||
private Immutable(String scheme, String host, int port, String path, String query, String fragment)
|
||||
{
|
||||
_scheme = null;
|
||||
_uri = null;
|
||||
|
||||
_scheme = URIUtil.normalizeScheme(scheme);
|
||||
_user = null;
|
||||
_host = null;
|
||||
_port = -1;
|
||||
_path = uri;
|
||||
_host = host;
|
||||
_port = port;
|
||||
_path = path;
|
||||
_canonicalPath = _path == null ? null : URIUtil.canonicalPath(_path);
|
||||
_param = null;
|
||||
_query = null;
|
||||
_fragment = null;
|
||||
_uri = uri;
|
||||
_canonicalPath = null;
|
||||
_query = query;
|
||||
_fragment = fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -340,19 +346,26 @@ public interface HttpURI
|
|||
out.append(_host);
|
||||
}
|
||||
|
||||
if (_port > 0)
|
||||
out.append(':').append(_port);
|
||||
int normalizedPort = URIUtil.normalizePortForScheme(_scheme, _port);
|
||||
if (normalizedPort > 0)
|
||||
out.append(':').append(normalizedPort);
|
||||
|
||||
// we output even if the input is an empty string (to match java URI / URL behaviors)
|
||||
boolean hasQuery = _query != null;
|
||||
boolean hasFragment = _fragment != null;
|
||||
|
||||
if (_path != null)
|
||||
out.append(_path);
|
||||
else if (hasQuery || hasFragment)
|
||||
out.append('/');
|
||||
|
||||
if (_query != null)
|
||||
if (hasQuery)
|
||||
out.append('?').append(_query);
|
||||
|
||||
if (_fragment != null)
|
||||
if (hasFragment)
|
||||
out.append('#').append(_fragment);
|
||||
|
||||
if (out.length() > 0)
|
||||
if (!out.isEmpty())
|
||||
_uri = out.toString();
|
||||
else
|
||||
_uri = "";
|
||||
|
@ -504,7 +517,7 @@ public interface HttpURI
|
|||
{
|
||||
try
|
||||
{
|
||||
return new URI(_scheme, null, _host, _port, _path, _query == null ? null : UrlEncoded.decodeString(_query), _fragment);
|
||||
return new URI(_scheme, null, _host, URIUtil.normalizePortForScheme(_scheme, _port), _path, _query == null ? null : UrlEncoded.decodeString(_query), _fragment);
|
||||
}
|
||||
catch (URISyntaxException x)
|
||||
{
|
||||
|
@ -616,7 +629,7 @@ public interface HttpURI
|
|||
{
|
||||
_uri = null;
|
||||
|
||||
_scheme = uri.getScheme();
|
||||
_scheme = URIUtil.normalizeScheme(uri.getScheme());
|
||||
_host = uri.getHost();
|
||||
if (_host == null && uri.getRawSchemeSpecificPart().startsWith("//"))
|
||||
_host = "";
|
||||
|
@ -631,13 +644,9 @@ public interface HttpURI
|
|||
|
||||
private Mutable(String scheme, String host, int port, String pathQuery)
|
||||
{
|
||||
// TODO review if this should be here
|
||||
if (port == HttpScheme.getDefaultPort(scheme))
|
||||
port = 0;
|
||||
|
||||
_uri = null;
|
||||
|
||||
_scheme = scheme;
|
||||
_scheme = URIUtil.normalizeScheme(scheme);
|
||||
_host = host;
|
||||
_port = port;
|
||||
|
||||
|
@ -960,7 +969,7 @@ public interface HttpURI
|
|||
|
||||
public Mutable scheme(String scheme)
|
||||
{
|
||||
_scheme = scheme;
|
||||
_scheme = URIUtil.normalizeScheme(scheme);
|
||||
_uri = null;
|
||||
return this;
|
||||
}
|
||||
|
@ -1122,7 +1131,7 @@ public interface HttpURI
|
|||
{
|
||||
case ':':
|
||||
// must have been a scheme
|
||||
_scheme = uri.substring(mark, i);
|
||||
_scheme = URIUtil.normalizeScheme(uri.substring(mark, i));
|
||||
// Start again with scheme set
|
||||
state = State.START;
|
||||
break;
|
||||
|
|
|
@ -940,4 +940,141 @@ public class HttpURITest
|
|||
{
|
||||
assertThat(UriCompliance.from(UriCompliance.DEFAULT.getName()), sameInstance(UriCompliance.DEFAULT));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> concatNormalizedURIShortCases()
|
||||
{
|
||||
return Stream.of(
|
||||
// Default behaviors of stripping a port number based on scheme
|
||||
Arguments.of("http", "example.org", 80, "http://example.org"),
|
||||
Arguments.of("https", "example.org", 443, "https://example.org"),
|
||||
Arguments.of("ws", "example.org", 80, "ws://example.org"),
|
||||
Arguments.of("wss", "example.org", 443, "wss://example.org"),
|
||||
// Mismatches between scheme and port
|
||||
Arguments.of("http", "example.org", 443, "http://example.org:443"),
|
||||
Arguments.of("https", "example.org", 80, "https://example.org:80"),
|
||||
Arguments.of("ws", "example.org", 443, "ws://example.org:443"),
|
||||
Arguments.of("wss", "example.org", 80, "wss://example.org:80"),
|
||||
// Odd ports
|
||||
Arguments.of("http", "example.org", 12345, "http://example.org:12345"),
|
||||
Arguments.of("https", "example.org", 54321, "https://example.org:54321"),
|
||||
Arguments.of("ws", "example.org", 6666, "ws://example.org:6666"),
|
||||
Arguments.of("wss", "example.org", 7777, "wss://example.org:7777"),
|
||||
// Non-lowercase Schemes
|
||||
Arguments.of("HTTP", "example.org", 8181, "http://example.org:8181"),
|
||||
Arguments.of("hTTps", "example.org", 443, "https://example.org"),
|
||||
Arguments.of("WS", "example.org", 8282, "ws://example.org:8282"),
|
||||
Arguments.of("wsS", "example.org", 8383, "wss://example.org:8383"),
|
||||
// Undefined Ports
|
||||
Arguments.of("http", "example.org", 0, "http://example.org"),
|
||||
Arguments.of("https", "example.org", -1, "https://example.org"),
|
||||
Arguments.of("ws", "example.org", -80, "ws://example.org"),
|
||||
Arguments.of("wss", "example.org", -2, "wss://example.org"),
|
||||
// Unrecognized (non-http) schemes
|
||||
Arguments.of("foo", "example.org", 0, "foo://example.org"),
|
||||
Arguments.of("ssh", "example.org", 22, "ssh://example.org"),
|
||||
Arguments.of("ftp", "example.org", 21, "ftp://example.org"),
|
||||
Arguments.of("ssh", "example.org", 2222, "ssh://example.org:2222"),
|
||||
Arguments.of("ftp", "example.org", 2121, "ftp://example.org:2121"),
|
||||
Arguments.of("file", "etc", -1, "file://etc")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("concatNormalizedURIShortCases")
|
||||
public void testFromShortAsStringNormalized(String scheme, String server, int port, String expectedStr)
|
||||
{
|
||||
HttpURI httpURI = HttpURI.from(scheme, server, port, null);
|
||||
assertThat(httpURI.asString(), is(expectedStr));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> concatNormalizedURICases()
|
||||
{
|
||||
return Stream.of(
|
||||
// Default behaviors of stripping a port number based on scheme
|
||||
Arguments.of("http", "example.org", 80, "/", null, null, "http://example.org/"),
|
||||
Arguments.of("https", "example.org", 443, "/", null, null, "https://example.org/"),
|
||||
Arguments.of("ws", "example.org", 80, "/", null, null, "ws://example.org/"),
|
||||
Arguments.of("wss", "example.org", 443, "/", null, null, "wss://example.org/"),
|
||||
// Mismatches between scheme and port
|
||||
Arguments.of("http", "example.org", 443, "/", null, null, "http://example.org:443/"),
|
||||
Arguments.of("https", "example.org", 80, "/", null, null, "https://example.org:80/"),
|
||||
Arguments.of("ws", "example.org", 443, "/", null, null, "ws://example.org:443/"),
|
||||
Arguments.of("wss", "example.org", 80, "/", null, null, "wss://example.org:80/"),
|
||||
// Odd ports
|
||||
Arguments.of("http", "example.org", 12345, "/", null, null, "http://example.org:12345/"),
|
||||
Arguments.of("https", "example.org", 54321, "/", null, null, "https://example.org:54321/"),
|
||||
Arguments.of("ws", "example.org", 6666, "/", null, null, "ws://example.org:6666/"),
|
||||
Arguments.of("wss", "example.org", 7777, "/", null, null, "wss://example.org:7777/"),
|
||||
// Non-lowercase Schemes
|
||||
Arguments.of("HTTP", "example.org", 8181, "/", null, null, "http://example.org:8181/"),
|
||||
Arguments.of("hTTps", "example.org", 443, "/", null, null, "https://example.org/"),
|
||||
Arguments.of("WS", "example.org", 8282, "/", null, null, "ws://example.org:8282/"),
|
||||
Arguments.of("wsS", "example.org", 8383, "/", null, null, "wss://example.org:8383/"),
|
||||
// Undefined Ports
|
||||
Arguments.of("http", "example.org", 0, "/", null, null, "http://example.org/"),
|
||||
Arguments.of("https", "example.org", -1, "/", null, null, "https://example.org/"),
|
||||
Arguments.of("ws", "example.org", -80, "/", null, null, "ws://example.org/"),
|
||||
Arguments.of("wss", "example.org", -2, "/", null, null, "wss://example.org/"),
|
||||
// Unrecognized (non-http) schemes
|
||||
Arguments.of("foo", "example.org", 0, "/", null, null, "foo://example.org/"),
|
||||
Arguments.of("ssh", "example.org", 22, "/", null, null, "ssh://example.org/"),
|
||||
Arguments.of("ftp", "example.org", 21, "/", null, null, "ftp://example.org/"),
|
||||
Arguments.of("ssh", "example.org", 2222, "/", null, null, "ssh://example.org:2222/"),
|
||||
Arguments.of("ftp", "example.org", 2121, "/", null, null, "ftp://example.org:2121/"),
|
||||
// Path choices
|
||||
Arguments.of("http", "example.org", 0, "/a/b/c/d", null, null, "http://example.org/a/b/c/d"),
|
||||
Arguments.of("http", "example.org", 0, "/a%20b/c%20d", null, null, "http://example.org/a%20b/c%20d"),
|
||||
// Query specified
|
||||
Arguments.of("http", "example.org", 0, "/", "a=b", null, "http://example.org/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, "/documentation/latest/", "a=b", null, "http://example.org/documentation/latest/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, null, "a=b", null, "http://example.org/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, null, "", null, "http://example.org/?"),
|
||||
// Fragment specified
|
||||
Arguments.of("http", "example.org", 0, "/", null, "", "http://example.org/#"),
|
||||
Arguments.of("http", "example.org", 0, "/", null, "toc", "http://example.org/#toc"),
|
||||
Arguments.of("http", "example.org", 0, null, null, "toc", "http://example.org/#toc"),
|
||||
// Empty query & fragment - behavior matches java URI and URL
|
||||
Arguments.of("http", "example.org", 0, null, "", "", "http://example.org/?#")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("concatNormalizedURICases")
|
||||
public void testFromAsStringNormalized(String scheme, String server, int port, String path, String query, String fragment, String expectedStr)
|
||||
{
|
||||
HttpURI httpURI = HttpURI.from(scheme, server, port, path, query, fragment);
|
||||
assertThat(httpURI.asString(), is(expectedStr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests of parameters that result in undesired behaviors.
|
||||
* {@link HttpURI#from(String, String, int, String)}
|
||||
*/
|
||||
public static Stream<Arguments> fromBad()
|
||||
{
|
||||
return Stream.of(
|
||||
// bad schemes
|
||||
Arguments.of(null, "example.org", 0, "//example.org"),
|
||||
Arguments.of("", "example.org", 0, "://example.org"),
|
||||
Arguments.of("\t", "example.org", 0, "\t://example.org"),
|
||||
Arguments.of(" ", "example.org", 0, " ://example.org"),
|
||||
// bad ports
|
||||
Arguments.of("http", "example.org", 1_000_000, "http://example.org:1000000"),
|
||||
// bad ports
|
||||
Arguments.of("ws", "example.org", -222333, "ws://example.org"), // negative port same as -1, i.e. not set.
|
||||
// bad servers
|
||||
Arguments.of("http", null, 0, "http:"),
|
||||
Arguments.of("http", "", 0, "http://"),
|
||||
Arguments.of("http", "\t", 0, "http://\t"),
|
||||
Arguments.of("http", " ", 0, "http:// ")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("fromBad")
|
||||
public void testFromBad(String scheme, String server, int port, String expectedStr)
|
||||
{
|
||||
HttpURI httpURI = HttpURI.from(scheme, server, port, null);
|
||||
assertThat(httpURI.asString(), is(expectedStr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -672,8 +672,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator
|
|||
|
||||
private String getRedirectUri(Request request)
|
||||
{
|
||||
final StringBuffer redirectUri = new StringBuffer(128);
|
||||
URIUtil.appendSchemeHostPort(redirectUri, request.getHttpURI().getScheme(),
|
||||
final StringBuilder redirectUri = URIUtil.newURIBuilder(request.getHttpURI().getScheme(),
|
||||
Request.getServerName(request), Request.getServerPort(request));
|
||||
redirectUri.append(URIUtil.addPaths(request.getContext().getContextPath(), _redirectPath));
|
||||
return redirectUri.toString();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.rewrite.handler;
|
||||
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
/**
|
||||
* <p>Sets the request URI scheme, by default {@code https}.</p>
|
||||
|
@ -29,7 +30,7 @@ public class ForwardedSchemeHeaderRule extends HeaderRule
|
|||
|
||||
public void setScheme(String scheme)
|
||||
{
|
||||
_scheme = scheme;
|
||||
_scheme = URIUtil.normalizeScheme(scheme);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -134,7 +134,7 @@ public class SecurityHandlerTest
|
|||
|
||||
response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n");
|
||||
assertThat(response, containsString("HTTP/1.1 302 Found"));
|
||||
assertThat(response, containsString("Location: BWTP://"));
|
||||
assertThat(response, containsString("Location: bwtp://"));
|
||||
assertThat(response, containsString(":9999"));
|
||||
assertThat(response, not(containsString("OK")));
|
||||
|
||||
|
@ -161,7 +161,7 @@ public class SecurityHandlerTest
|
|||
|
||||
response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n");
|
||||
assertThat(response, containsString("HTTP/1.1 302 Found"));
|
||||
assertThat(response, containsString("Location: BWTP://"));
|
||||
assertThat(response, containsString("Location: bwtp://"));
|
||||
assertThat(response, containsString(":9999"));
|
||||
assertThat(response, not(containsString("OK")));
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ package org.eclipse.jetty.server;
|
|||
import org.eclipse.jetty.http.HostPortHttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
/**
|
||||
* Adds a missing {@code Host} header (for example, HTTP 1.0 or 2.0 requests).
|
||||
|
@ -58,7 +58,7 @@ public class HostHeaderCustomizer implements HttpConfiguration.Customizer
|
|||
return request;
|
||||
|
||||
String host = serverName == null ? Request.getServerName(request) : serverName;
|
||||
int port = HttpScheme.normalizePort(request.getHttpURI().getScheme(), serverPort == 0 ? Request.getServerPort(request) : serverPort);
|
||||
int port = URIUtil.normalizePortForScheme(request.getHttpURI().getScheme(), serverPort == 0 ? Request.getServerPort(request) : serverPort);
|
||||
|
||||
HttpURI uri = (serverName != null || serverPort > 0)
|
||||
? HttpURI.build(request.getHttpURI()).authority(host, port).asImmutable()
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.jetty.http.UriCompliance;
|
|||
import org.eclipse.jetty.util.HostPort;
|
||||
import org.eclipse.jetty.util.Index;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
|
@ -476,7 +477,7 @@ public class HttpConfiguration implements Dumpable
|
|||
*/
|
||||
public void setSecureScheme(String secureScheme)
|
||||
{
|
||||
_secureScheme = secureScheme;
|
||||
_secureScheme = URIUtil.normalizeScheme(secureScheme);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -356,10 +356,7 @@ public interface Response extends Content.Sink
|
|||
if (!request.getConnectionMetaData().getHttpConfiguration().isRelativeRedirectAllowed())
|
||||
{
|
||||
// make the location an absolute URI
|
||||
StringBuilder url = new StringBuilder(128);
|
||||
URIUtil.appendSchemeHostPort(url, uri.getScheme(), Request.getServerName(request), Request.getServerPort(request));
|
||||
url.append(location);
|
||||
location = url.toString();
|
||||
location = URIUtil.newURI(uri.getScheme(), Request.getServerName(request), Request.getServerPort(request), location, null);
|
||||
}
|
||||
}
|
||||
return location;
|
||||
|
|
|
@ -70,6 +70,7 @@ import org.eclipse.jetty.util.HostPort;
|
|||
import org.eclipse.jetty.util.IteratingCallback;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.thread.Invocable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -1218,7 +1219,7 @@ public class HttpConnection extends AbstractMetaDataConnection implements Runnab
|
|||
{
|
||||
HostPort hostPort = _hostField == null ? getServerAuthority() : _hostField.getHostPort();
|
||||
int port = hostPort.getPort();
|
||||
if (port == HttpScheme.getDefaultPort(_uri.getScheme()))
|
||||
if (port == URIUtil.getDefaultPortForScheme(_uri.getScheme()))
|
||||
port = -1;
|
||||
_uri.authority(hostPort.getHost(), port);
|
||||
}
|
||||
|
|
|
@ -666,7 +666,10 @@ public abstract class AbstractSessionManager extends ContainerLifeCycle implemen
|
|||
path = (path == null ? "" : path);
|
||||
int port = httpURI.getPort();
|
||||
if (port < 0)
|
||||
port = HttpScheme.getDefaultPort(httpURI.getScheme());
|
||||
{
|
||||
String scheme = httpURI.getScheme();
|
||||
port = URIUtil.getDefaultPortForScheme(scheme);
|
||||
}
|
||||
|
||||
// Is it the same server?
|
||||
if (!Request.getServerName(request).equalsIgnoreCase(httpURI.getHost()))
|
||||
|
|
|
@ -1359,6 +1359,19 @@ public final class URIUtil
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new URI from the arguments, handling IPv6 host encoding and default ports
|
||||
*
|
||||
* @param scheme the URI scheme
|
||||
* @param server the URI server
|
||||
* @param port the URI port
|
||||
* @return A String URI
|
||||
*/
|
||||
public static String newURI(String scheme, String server, int port)
|
||||
{
|
||||
return newURI(scheme, server, port, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new URI from the arguments, handling IPv6 host encoding and default ports
|
||||
*
|
||||
|
@ -1370,11 +1383,36 @@ public final class URIUtil
|
|||
* @return A String URI
|
||||
*/
|
||||
public static String newURI(String scheme, String server, int port, String path, String query)
|
||||
{
|
||||
return newURI(scheme, server, port, path, query, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new URI from the arguments, handling IPv6 host encoding and default ports
|
||||
*
|
||||
* @param scheme the URI scheme
|
||||
* @param server the URI server
|
||||
* @param port the URI port
|
||||
* @param path the URI path
|
||||
* @param query the URI query
|
||||
* @param fragment the URI fragment
|
||||
* @return A String URI
|
||||
*/
|
||||
public static String newURI(String scheme, String server, int port, String path, String query, String fragment)
|
||||
{
|
||||
StringBuilder builder = newURIBuilder(scheme, server, port);
|
||||
builder.append(path);
|
||||
if (query != null && query.length() > 0)
|
||||
// check only for null, as empty query/fragment have meaning.
|
||||
// this also matches the behavior of java URL & URI
|
||||
boolean hasQuery = query != null;
|
||||
boolean hasFragment = fragment != null;
|
||||
if (StringUtil.isNotBlank(path))
|
||||
builder.append(path);
|
||||
else if (hasQuery || hasFragment)
|
||||
builder.append('/');
|
||||
if (hasQuery)
|
||||
builder.append('?').append(query);
|
||||
if (hasFragment)
|
||||
builder.append('#').append(fragment);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
@ -1388,7 +1426,7 @@ public final class URIUtil
|
|||
*/
|
||||
public static StringBuilder newURIBuilder(String scheme, String server, int port)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuilder builder = new StringBuilder(128);
|
||||
appendSchemeHostPort(builder, scheme, server, port);
|
||||
return builder;
|
||||
}
|
||||
|
@ -1403,28 +1441,11 @@ public final class URIUtil
|
|||
*/
|
||||
public static void appendSchemeHostPort(StringBuilder url, String scheme, String server, int port)
|
||||
{
|
||||
scheme = normalizeScheme(scheme);
|
||||
url.append(scheme).append("://").append(HostPort.normalizeHost(server));
|
||||
|
||||
port = normalizePortForScheme(scheme, port);
|
||||
if (port > 0)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case "ws":
|
||||
case "http":
|
||||
if (port != 80)
|
||||
url.append(':').append(port);
|
||||
break;
|
||||
|
||||
case "wss":
|
||||
case "https":
|
||||
if (port != 443)
|
||||
url.append(':').append(port);
|
||||
break;
|
||||
|
||||
default:
|
||||
url.append(':').append(port);
|
||||
}
|
||||
}
|
||||
url.append(':').append(port);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1434,31 +1455,16 @@ public final class URIUtil
|
|||
* @param scheme the URI scheme
|
||||
* @param server the URI server
|
||||
* @param port the URI port
|
||||
* @deprecated Use {@link #appendSchemeHostPort(StringBuilder, String, String, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void appendSchemeHostPort(StringBuffer url, String scheme, String server, int port)
|
||||
{
|
||||
scheme = normalizeScheme(scheme);
|
||||
url.append(scheme).append("://").append(HostPort.normalizeHost(server));
|
||||
|
||||
port = normalizePortForScheme(scheme, port);
|
||||
if (port > 0)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case "ws":
|
||||
case "http":
|
||||
if (port != 80)
|
||||
url.append(':').append(port);
|
||||
break;
|
||||
|
||||
case "wss":
|
||||
case "https":
|
||||
if (port != 443)
|
||||
url.append(':').append(port);
|
||||
break;
|
||||
|
||||
default:
|
||||
url.append(':').append(port);
|
||||
}
|
||||
}
|
||||
url.append(':').append(port);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1925,4 +1931,52 @@ public final class URIUtil
|
|||
.map(URIUtil::unwrapContainer)
|
||||
.map(URIUtil::correctFileURI);
|
||||
}
|
||||
|
||||
private static final Index<Integer> DEFAULT_PORT_FOR_SCHEME = new Index.Builder<Integer>()
|
||||
.caseSensitive(false)
|
||||
.with("ftp", 21)
|
||||
.with("ssh", 22)
|
||||
.with("telnet", 23)
|
||||
.with("smtp", 25)
|
||||
.with("http", 80)
|
||||
.with("ws", 80)
|
||||
.with("https", 443)
|
||||
.with("wss", 443)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Get the default port for some well known schemes
|
||||
* @param scheme The scheme
|
||||
* @return The default port or -1 if not known
|
||||
*/
|
||||
public static int getDefaultPortForScheme(String scheme)
|
||||
{
|
||||
if (scheme == null)
|
||||
return -1;
|
||||
Integer port = DEFAULT_PORT_FOR_SCHEME.get(scheme);
|
||||
return port == null ? -1 : port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the scheme
|
||||
* @param scheme The scheme to normalize
|
||||
* @return The normalized version of the scheme
|
||||
*/
|
||||
public static String normalizeScheme(String scheme)
|
||||
{
|
||||
return scheme == null ? null : StringUtil.asciiToLowerCase(scheme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a port for a given scheme
|
||||
* @param scheme The scheme
|
||||
* @param port The port to normalize
|
||||
* @return The port number or 0 if provided port was less than 0 or was equal to the default port for the scheme
|
||||
*/
|
||||
public static int normalizePortForScheme(String scheme, int port)
|
||||
{
|
||||
if (port <= 0)
|
||||
return 0;
|
||||
return port == getDefaultPortForScheme(scheme) ? 0 : port;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.junit.jupiter.api.condition.OS;
|
|||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
|
@ -47,6 +48,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
/**
|
||||
* URIUtil Tests.
|
||||
|
@ -1186,7 +1188,7 @@ public class URIUtilTest
|
|||
assertThat(uris, contains(expected));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> appendSchemeHostPortCases()
|
||||
public static Stream<Arguments> schemeHostPortShortCases()
|
||||
{
|
||||
return Stream.of(
|
||||
// Default behaviors of stripping a port number based on scheme
|
||||
|
@ -1203,12 +1205,29 @@ public class URIUtilTest
|
|||
Arguments.of("http", "example.org", 12345, "http://example.org:12345"),
|
||||
Arguments.of("https", "example.org", 54321, "https://example.org:54321"),
|
||||
Arguments.of("ws", "example.org", 6666, "ws://example.org:6666"),
|
||||
Arguments.of("wss", "example.org", 7777, "wss://example.org:7777")
|
||||
Arguments.of("wss", "example.org", 7777, "wss://example.org:7777"),
|
||||
// Non-lowercase Schemes
|
||||
Arguments.of("HTTP", "example.org", 8181, "http://example.org:8181"),
|
||||
Arguments.of("hTTps", "example.org", 443, "https://example.org"),
|
||||
Arguments.of("WS", "example.org", 8282, "ws://example.org:8282"),
|
||||
Arguments.of("wsS", "example.org", 8383, "wss://example.org:8383"),
|
||||
// Undefined Ports
|
||||
Arguments.of("http", "example.org", 0, "http://example.org"),
|
||||
Arguments.of("https", "example.org", -1, "https://example.org"),
|
||||
Arguments.of("ws", "example.org", -80, "ws://example.org"),
|
||||
Arguments.of("wss", "example.org", -2, "wss://example.org"),
|
||||
// Unrecognized (non-http) schemes
|
||||
Arguments.of("foo", "example.org", 0, "foo://example.org"),
|
||||
Arguments.of("ssh", "example.org", 22, "ssh://example.org"),
|
||||
Arguments.of("ftp", "example.org", 21, "ftp://example.org"),
|
||||
Arguments.of("ssh", "example.org", 2222, "ssh://example.org:2222"),
|
||||
Arguments.of("ftp", "example.org", 2121, "ftp://example.org:2121"),
|
||||
Arguments.of("file", "etc", -1, "file://etc")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("appendSchemeHostPortCases")
|
||||
@MethodSource("schemeHostPortShortCases")
|
||||
public void testAppendSchemeHostPortBuilder(String scheme, String server, int port, String expectedStr)
|
||||
{
|
||||
StringBuilder actual = new StringBuilder();
|
||||
|
@ -1217,11 +1236,211 @@ public class URIUtilTest
|
|||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("appendSchemeHostPortCases")
|
||||
@MethodSource("schemeHostPortShortCases")
|
||||
public void testAppendSchemeHostPortBuffer(String scheme, String server, int port, String expectedStr)
|
||||
{
|
||||
StringBuffer actual = new StringBuffer();
|
||||
URIUtil.appendSchemeHostPort(actual, scheme, server, port);
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
public static List<Arguments> getNewURICases()
|
||||
{
|
||||
List<Arguments> cases = new ArrayList<>();
|
||||
|
||||
cases.addAll(List.of(
|
||||
// Default behaviors of stripping a port number based on scheme
|
||||
// Query specified
|
||||
Arguments.of("http", "example.org", 0, "/", "a=b", null, "http://example.org/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, "/documentation/latest/", "a=b", null, "http://example.org/documentation/latest/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, null, "a=b", null, "http://example.org/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, null, "", null, "http://example.org/?")
|
||||
));
|
||||
return cases;
|
||||
}
|
||||
|
||||
public static List<Arguments> schemeHostPortCases()
|
||||
{
|
||||
return List.of(
|
||||
// Default behaviors of stripping a port number based on scheme
|
||||
Arguments.of("http", "example.org", 80, "http://example.org"),
|
||||
Arguments.of("https", "example.org", 443, "https://example.org"),
|
||||
Arguments.of("ws", "example.org", 80, "ws://example.org"),
|
||||
Arguments.of("wss", "example.org", 443, "wss://example.org"),
|
||||
// Mismatches between scheme and port
|
||||
Arguments.of("http", "example.org", 443, "http://example.org:443"),
|
||||
Arguments.of("https", "example.org", 80, "https://example.org:80"),
|
||||
Arguments.of("ws", "example.org", 443, "ws://example.org:443"),
|
||||
Arguments.of("wss", "example.org", 80, "wss://example.org:80"),
|
||||
// Odd ports
|
||||
Arguments.of("http", "example.org", 12345, "http://example.org:12345"),
|
||||
Arguments.of("https", "example.org", 54321, "https://example.org:54321"),
|
||||
Arguments.of("ws", "example.org", 6666, "ws://example.org:6666"),
|
||||
Arguments.of("wss", "example.org", 7777, "wss://example.org:7777"),
|
||||
// Non-lowercase Schemes
|
||||
Arguments.of("HTTP", "example.org", 8181, "http://example.org:8181"),
|
||||
Arguments.of("hTTps", "example.org", 443, "https://example.org"),
|
||||
Arguments.of("WS", "example.org", 8282, "ws://example.org:8282"),
|
||||
Arguments.of("wsS", "example.org", 8383, "wss://example.org:8383"),
|
||||
// Undefined Ports
|
||||
Arguments.of("http", "example.org", 0, "http://example.org"),
|
||||
Arguments.of("https", "example.org", -1, "https://example.org"),
|
||||
Arguments.of("ws", "example.org", -80, "ws://example.org"),
|
||||
Arguments.of("wss", "example.org", -2, "wss://example.org"),
|
||||
// Unrecognized (non-http) schemes
|
||||
Arguments.of("foo", "example.org", 0, "foo://example.org"),
|
||||
Arguments.of("ssh", "example.org", 22, "ssh://example.org"),
|
||||
Arguments.of("ftp", "example.org", 21, "ftp://example.org"),
|
||||
Arguments.of("ssh", "example.org", 2222, "ssh://example.org:2222"),
|
||||
Arguments.of("ftp", "example.org", 2121, "ftp://example.org:2121")
|
||||
);
|
||||
}
|
||||
|
||||
public static List<Arguments> schemeHostPortPathCases()
|
||||
{
|
||||
List<Arguments> cases = new ArrayList<>();
|
||||
|
||||
cases.addAll(List.of(
|
||||
// Default behaviors of stripping a port number based on scheme
|
||||
Arguments.of("http", "example.org", 80, "/", null, null, "http://example.org/"),
|
||||
Arguments.of("https", "example.org", 443, "/", null, null, "https://example.org/"),
|
||||
Arguments.of("ws", "example.org", 80, "/", null, null, "ws://example.org/"),
|
||||
Arguments.of("wss", "example.org", 443, "/", null, null, "wss://example.org/"),
|
||||
// Mismatches between scheme and port
|
||||
Arguments.of("http", "example.org", 443, "/", null, null, "http://example.org:443/"),
|
||||
Arguments.of("https", "example.org", 80, "/", null, null, "https://example.org:80/"),
|
||||
Arguments.of("ws", "example.org", 443, "/", null, null, "ws://example.org:443/"),
|
||||
Arguments.of("wss", "example.org", 80, "/", null, null, "wss://example.org:80/"),
|
||||
// Odd ports
|
||||
Arguments.of("http", "example.org", 12345, "/", null, null, "http://example.org:12345/"),
|
||||
Arguments.of("https", "example.org", 54321, "/", null, null, "https://example.org:54321/"),
|
||||
Arguments.of("ws", "example.org", 6666, "/", null, null, "ws://example.org:6666/"),
|
||||
Arguments.of("wss", "example.org", 7777, "/", null, null, "wss://example.org:7777/"),
|
||||
// Non-lowercase Schemes
|
||||
Arguments.of("HTTP", "example.org", 8181, "/", null, null, "http://example.org:8181/"),
|
||||
Arguments.of("hTTps", "example.org", 443, "/", null, null, "https://example.org/"),
|
||||
Arguments.of("WS", "example.org", 8282, "/", null, null, "ws://example.org:8282/"),
|
||||
Arguments.of("wsS", "example.org", 8383, "/", null, null, "wss://example.org:8383/"),
|
||||
// Undefined Ports
|
||||
Arguments.of("http", "example.org", 0, "/", null, null, "http://example.org/"),
|
||||
Arguments.of("https", "example.org", -1, "/", null, null, "https://example.org/"),
|
||||
Arguments.of("ws", "example.org", -80, "/", null, null, "ws://example.org/"),
|
||||
Arguments.of("wss", "example.org", -2, "/", null, null, "wss://example.org/"),
|
||||
// Unrecognized (non-http) schemes
|
||||
Arguments.of("foo", "example.org", 0, "/", null, null, "foo://example.org/"),
|
||||
Arguments.of("ssh", "example.org", 22, "/", null, null, "ssh://example.org/"),
|
||||
Arguments.of("ftp", "example.org", 21, "/", null, null, "ftp://example.org/"),
|
||||
Arguments.of("ssh", "example.org", 2222, "/", null, null, "ssh://example.org:2222/"),
|
||||
Arguments.of("ftp", "example.org", 2121, "/", null, null, "ftp://example.org:2121/"),
|
||||
// Path choices
|
||||
Arguments.of("http", "example.org", 0, "/a/b/c/d", null, null, "http://example.org/a/b/c/d"),
|
||||
Arguments.of("http", "example.org", 0, "/a%20b/c%20d", null, null, "http://example.org/a%20b/c%20d"),
|
||||
// Query specified
|
||||
Arguments.of("http", "example.org", 0, "/", "a=b", null, "http://example.org/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, "/documentation/latest/", "a=b", null, "http://example.org/documentation/latest/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, null, "a=b", null, "http://example.org/?a=b"),
|
||||
Arguments.of("http", "example.org", 0, null, "", null, "http://example.org/?")
|
||||
));
|
||||
return cases;
|
||||
}
|
||||
|
||||
public static List<Arguments> schemeHostPortFragmentCases()
|
||||
{
|
||||
List<Arguments> cases = new ArrayList<>();
|
||||
cases.addAll(schemeHostPortPathCases());
|
||||
|
||||
cases.addAll(List.of(
|
||||
// Fragment specified
|
||||
Arguments.of("http", "example.org", 0, "/", null, "", "http://example.org/#"),
|
||||
Arguments.of("http", "example.org", 0, "/", null, "toc", "http://example.org/#toc"),
|
||||
Arguments.of("http", "example.org", 0, null, null, "toc", "http://example.org/#toc"),
|
||||
// Empty query & fragment - behavior matches java URI and URL
|
||||
Arguments.of("http", "example.org", 0, null, "", "", "http://example.org/?#")
|
||||
));
|
||||
|
||||
return cases;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("schemeHostPortCases")
|
||||
public void testNewURIShort(String scheme, String server, int port, String expectedStr)
|
||||
{
|
||||
String actual = URIUtil.newURI(scheme, server, port);
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("schemeHostPortPathCases")
|
||||
public void testNewURI(String scheme, String server, int port, String path, String query, String fragment, String expectedStr)
|
||||
{
|
||||
assumeTrue(StringUtil.isBlank(fragment), "Skip tests with fragments, as this newURI doesn't have them");
|
||||
String actual = URIUtil.newURI(scheme, server, port, path, query);
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("schemeHostPortFragmentCases")
|
||||
public void testNewURIFragment(String scheme, String server, int port, String path, String query, String fragment, String expectedStr)
|
||||
{
|
||||
String actual = URIUtil.newURI(scheme, server, port, path, query, fragment);
|
||||
assertEquals(expectedStr, actual.toString());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(value = {
|
||||
"http,80",
|
||||
"https,443",
|
||||
"ws,80",
|
||||
"wss,443",
|
||||
"ssh,22",
|
||||
"file,-1",
|
||||
"bundle,-1",
|
||||
"HTTP,80",
|
||||
"HttPs,443",
|
||||
"http+ssl,-1"
|
||||
})
|
||||
public void testGetDefaultPortForScheme(String scheme, int expectedPort)
|
||||
{
|
||||
int actual = URIUtil.getDefaultPortForScheme(scheme);
|
||||
assertEquals(expectedPort, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(value = {
|
||||
"http,80,0",
|
||||
"https,443,0",
|
||||
"https,8443,8443",
|
||||
"ws,80,0",
|
||||
"ws,9999,9999",
|
||||
"wss,443,0",
|
||||
"wss,-1,0",
|
||||
"wss,0,0",
|
||||
"ssh,22,0",
|
||||
"file,-1,0",
|
||||
"bundle,-1,0",
|
||||
"HTTP,80,0",
|
||||
"HttPs,443,0",
|
||||
"http+ssl,-1,0"
|
||||
})
|
||||
public void testNormalizePortForScheme(String scheme, int port, int expectedPort)
|
||||
{
|
||||
int actual = URIUtil.normalizePortForScheme(scheme, port);
|
||||
assertEquals(expectedPort, actual);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(value = {
|
||||
"http,http",
|
||||
"https,https",
|
||||
"HTTP,http",
|
||||
"WSS,wss",
|
||||
"WS,ws",
|
||||
"XRTP,xrtp",
|
||||
"Https,https"
|
||||
})
|
||||
public void testNormalizeScheme(String input, String expected)
|
||||
{
|
||||
String actual = URIUtil.normalizeScheme(input);
|
||||
assertThat(actual, is(expected));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.jetty.logging.StacklessLogging;
|
|||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
@ -77,7 +78,7 @@ public class WebSocketCloseTest extends WebSocketTester
|
|||
public void setup(State state, String scheme) throws Exception
|
||||
{
|
||||
boolean tls;
|
||||
switch (scheme)
|
||||
switch (URIUtil.normalizeScheme(scheme))
|
||||
{
|
||||
case "ws":
|
||||
tls = false;
|
||||
|
|
|
@ -102,17 +102,17 @@ public final class WSURI
|
|||
public static URI toWebsocket(final URI inputUri) throws URISyntaxException
|
||||
{
|
||||
Objects.requireNonNull(inputUri, "Input URI must not be null");
|
||||
String httpScheme = inputUri.getScheme();
|
||||
if (httpScheme == null)
|
||||
String scheme = inputUri.getScheme();
|
||||
if (scheme == null)
|
||||
throw new URISyntaxException(inputUri.toString(), "Undefined HTTP scheme");
|
||||
|
||||
if ("ws".equalsIgnoreCase(httpScheme) || "wss".equalsIgnoreCase(httpScheme))
|
||||
if ("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))
|
||||
return inputUri;
|
||||
|
||||
String afterScheme = inputUri.toString().substring(httpScheme.length());
|
||||
if ("http".equalsIgnoreCase(httpScheme))
|
||||
String afterScheme = inputUri.toString().substring(scheme.length());
|
||||
if ("http".equalsIgnoreCase(scheme))
|
||||
return new URI("ws" + afterScheme);
|
||||
if ("https".equalsIgnoreCase(httpScheme))
|
||||
if ("https".equalsIgnoreCase(scheme))
|
||||
return new URI("wss" + afterScheme);
|
||||
|
||||
throw new URISyntaxException(inputUri.toString(), "Unrecognized HTTP scheme");
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
/**
|
||||
* Specific implementation of {@link org.eclipse.jetty.ee10.proxy.AsyncProxyServlet.Transparent} for FastCGI.
|
||||
|
@ -195,7 +196,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
{
|
||||
String server = request.getServerName();
|
||||
int port = request.getServerPort();
|
||||
if (port != HttpScheme.getDefaultPort(request.getScheme()))
|
||||
if (port != URIUtil.getDefaultPortForScheme(request.getScheme()))
|
||||
server += ":" + port;
|
||||
String host = server;
|
||||
proxyRequest.headers(headers -> headers
|
||||
|
|
|
@ -65,7 +65,6 @@ import org.eclipse.jetty.http.HttpException;
|
|||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
@ -1017,7 +1016,7 @@ public class ServletApiRequest implements HttpServletRequest
|
|||
|
||||
// If no port specified, return the default port for the scheme
|
||||
if (port <= 0)
|
||||
return HttpScheme.getDefaultPort(getScheme());
|
||||
return URIUtil.getDefaultPortForScheme(getScheme());
|
||||
|
||||
// return a specific port
|
||||
return port;
|
||||
|
|
|
@ -35,9 +35,7 @@ import jakarta.servlet.ServletContext;
|
|||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletRequestWrapper;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.ServletResponseWrapper;
|
||||
import jakarta.servlet.WriteListener;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletMapping;
|
||||
|
@ -1519,7 +1517,7 @@ public class DispatcherTest
|
|||
assertEquals("/context/AssertForwardServlet", request.getRequestURI());
|
||||
assertEquals("/context", request.getContextPath());
|
||||
assertEquals("/AssertForwardServlet", request.getServletPath());
|
||||
assertEquals("http://local:80/context/AssertForwardServlet", request.getRequestURL().toString());
|
||||
assertEquals("http://local/context/AssertForwardServlet", request.getRequestURL().toString());
|
||||
|
||||
response.setContentType("text/html");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
|
|
|
@ -679,7 +679,7 @@ public class ErrorPageTest
|
|||
assertThat(responseBody, Matchers.containsString("ERROR_SERVLET: " + failServlet.getClass().getName()));
|
||||
assertThat(responseBody, Matchers.containsString("ERROR_REQUEST_URI: /fail/599"));
|
||||
assertThat(responseBody, Matchers.containsString("getQueryString()=[code=param]"));
|
||||
assertThat(responseBody, Matchers.containsString("getRequestURL()=[http://test:80/error/599?code=param]"));
|
||||
assertThat(responseBody, Matchers.containsString("getRequestURL()=[http://test/error/599?code=param]"));
|
||||
assertThat(responseBody, Matchers.containsString("getParameterMap().size=2"));
|
||||
assertThat(responseBody, Matchers.containsString("getParameterMap()[code]=[param]"));
|
||||
assertThat(responseBody, Matchers.containsString("getParameterMap()[value]=[zed]"));
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.http.HttpScheme;
|
|||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
@ -168,7 +169,7 @@ public class XmlBasedJettyServer
|
|||
|
||||
public void setScheme(String scheme)
|
||||
{
|
||||
this._scheme = scheme;
|
||||
this._scheme = URIUtil.normalizeScheme(scheme);
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
|
@ -196,11 +197,7 @@ public class XmlBasedJettyServer
|
|||
|
||||
public URI getServerURI()
|
||||
{
|
||||
StringBuffer uri = new StringBuffer();
|
||||
uri.append(this._scheme).append("://");
|
||||
uri.append(InetAddress.getLoopbackAddress().getHostAddress());
|
||||
uri.append(":").append(this._serverPort);
|
||||
return URI.create(uri.toString());
|
||||
return URI.create(URIUtil.newURI(_scheme, InetAddress.getLoopbackAddress().getHostAddress(), _serverPort));
|
||||
}
|
||||
|
||||
public Server getServer()
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
||||
/**
|
||||
* Specific implementation of {@link org.eclipse.jetty.ee9.proxy.AsyncProxyServlet.Transparent} for FastCGI.
|
||||
|
@ -195,7 +196,8 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
{
|
||||
String server = request.getServerName();
|
||||
int port = request.getServerPort();
|
||||
if (port != HttpScheme.getDefaultPort(request.getScheme()))
|
||||
String scheme = request.getScheme();
|
||||
if (port != URIUtil.getDefaultPortForScheme(scheme))
|
||||
server += ":" + port;
|
||||
String host = server;
|
||||
proxyRequest.headers(headers -> headers
|
||||
|
|
|
@ -1177,9 +1177,7 @@ public class Request implements HttpServletRequest
|
|||
*/
|
||||
public StringBuilder getRootURL()
|
||||
{
|
||||
StringBuilder url = new StringBuilder(128);
|
||||
URIUtil.appendSchemeHostPort(url, getScheme(), getServerName(), getServerPort());
|
||||
return url;
|
||||
return new StringBuilder(HttpURI.from(getScheme(), getServerName(), getServerPort(), null).asString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -347,7 +347,7 @@ public class Response implements HttpServletResponse
|
|||
path = (path == null ? "" : path);
|
||||
int port = uri.getPort();
|
||||
if (port < 0)
|
||||
port = HttpScheme.getDefaultPort(uri.getScheme());
|
||||
port = URIUtil.getDefaultPortForScheme(uri.getScheme());
|
||||
|
||||
// Is it the same server?
|
||||
if (!request.getServerName().equalsIgnoreCase(uri.getHost()))
|
||||
|
|
|
@ -81,9 +81,9 @@ public class SecuredRedirectHandler extends HandlerWrapper
|
|||
if (securePort > 0)
|
||||
{
|
||||
String secureScheme = httpConfig.getSecureScheme();
|
||||
String url = URIUtil.newURI(secureScheme, baseRequest.getServerName(), securePort, baseRequest.getRequestURI(), baseRequest.getQueryString());
|
||||
String uri = URIUtil.newURI(secureScheme, baseRequest.getServerName(), securePort, baseRequest.getRequestURI(), baseRequest.getQueryString());
|
||||
response.setContentLength(0);
|
||||
baseRequest.getResponse().sendRedirect(_redirectCode, url, true);
|
||||
baseRequest.getResponse().sendRedirect(_redirectCode, uri, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -292,8 +292,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator
|
|||
String redirectUri = null;
|
||||
if (_logoutRedirectPath != null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(128);
|
||||
URIUtil.appendSchemeHostPort(sb, request.getScheme(), request.getServerName(), request.getServerPort());
|
||||
StringBuilder sb = URIUtil.newURIBuilder(request.getScheme(), request.getServerName(), request.getServerPort());
|
||||
sb.append(baseRequest.getContextPath());
|
||||
sb.append(_logoutRedirectPath);
|
||||
redirectUri = sb.toString();
|
||||
|
@ -614,8 +613,7 @@ public class OpenIdAuthenticator extends LoginAuthenticator
|
|||
|
||||
private String getRedirectUri(HttpServletRequest request)
|
||||
{
|
||||
final StringBuffer redirectUri = new StringBuffer(128);
|
||||
URIUtil.appendSchemeHostPort(redirectUri, request.getScheme(),
|
||||
final StringBuilder redirectUri = URIUtil.newURIBuilder(request.getScheme(),
|
||||
request.getServerName(), request.getServerPort());
|
||||
redirectUri.append(request.getContextPath());
|
||||
redirectUri.append(_redirectPath);
|
||||
|
|
|
@ -89,6 +89,7 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
@ -841,7 +842,7 @@ public class ProxyServletTest
|
|||
int serverPort = serverConnector.getLocalPort();
|
||||
if (HttpScheme.HTTPS.is(scheme))
|
||||
serverPort = tlsServerConnector.getLocalPort();
|
||||
String proxyTo = scheme + "://localhost:" + serverPort;
|
||||
String proxyTo = URIUtil.normalizeScheme(scheme) + "://localhost:" + serverPort;
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("proxyTo", proxyTo);
|
||||
params.put("prefix", prefix);
|
||||
|
|
|
@ -138,7 +138,7 @@ public class DataConstraintsTest
|
|||
|
||||
response = _connector.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n");
|
||||
assertThat(response, Matchers.containsString("HTTP/1.1 302 Found"));
|
||||
assertThat(response, Matchers.containsString("Location: BWTP://"));
|
||||
assertThat(response, Matchers.containsString("Location: bwtp://"));
|
||||
assertThat(response, Matchers.containsString(":9999"));
|
||||
|
||||
response = _connectorS.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n");
|
||||
|
@ -166,7 +166,7 @@ public class DataConstraintsTest
|
|||
|
||||
response = _connector.getResponse("GET /ctx/confid/info HTTP/1.0\r\n\r\n");
|
||||
assertThat(response, Matchers.containsString("HTTP/1.1 302 Found"));
|
||||
assertThat(response, Matchers.containsString("Location: BWTP://"));
|
||||
assertThat(response, Matchers.containsString("Location: bwtp://"));
|
||||
assertThat(response, Matchers.containsString(":9999"));
|
||||
|
||||
response = _connectorS.getResponse("GET /ctx/confid/info HTTP/1.0\r\n\r\n");
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.ee9.test.support;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
|
@ -30,6 +29,7 @@ import org.eclipse.jetty.http.HttpScheme;
|
|||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
@ -169,7 +169,7 @@ public class XmlBasedJettyServer
|
|||
|
||||
public void setScheme(String scheme)
|
||||
{
|
||||
this._scheme = scheme;
|
||||
this._scheme = URIUtil.normalizeScheme(scheme);
|
||||
}
|
||||
|
||||
public void start() throws Exception
|
||||
|
|
Loading…
Reference in New Issue