* Issue #7277 - Allow `Request.getLocalName()` and `.getLocalPort()` to be overridden (#7316) * Introduce `HttpConfiguration.setServerAuthority(HostPort)` to influence `ServletRequest.getServerName()` and `ServletRequest.getServerPort()` * Introduce `HttpConfiguration.setLocalAddress(SocketAddress)` to influence `ServletRequest.getLocalName()`, `ServletRequest.getLocalPort()`, and `ServletRequest.getLocalAddr()` * Correcting Request URI logic on abs-uri without authority * Adding test cases Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
This commit is contained in:
parent
3042f2b2bf
commit
1984d2de11
|
@ -156,6 +156,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
private long _shutdownIdleTimeout = 1000L;
|
||||
private String _defaultProtocol;
|
||||
private ConnectionFactory _defaultConnectionFactory;
|
||||
/* The name used to link up virtual host configuration to named connectors */
|
||||
private String _name;
|
||||
private int _acceptorPriorityDelta = -2;
|
||||
private boolean _accepting = true;
|
||||
|
@ -348,6 +349,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
}
|
||||
|
||||
_lease = ThreadPoolBudget.leaseFrom(getExecutor(), this, _acceptors.length);
|
||||
|
||||
super.doStart();
|
||||
|
||||
for (int i = 0; i < _acceptors.length; i++)
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.nio.ByteBuffer;
|
|||
import java.util.ArrayList;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
@ -97,7 +98,7 @@ public abstract class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
public HttpChannel(Connector connector, HttpConfiguration configuration, EndPoint endPoint, HttpTransport transport)
|
||||
{
|
||||
_connector = connector;
|
||||
_configuration = configuration;
|
||||
_configuration = Objects.requireNonNull(configuration);
|
||||
_endPoint = endPoint;
|
||||
_transport = transport;
|
||||
|
||||
|
@ -325,8 +326,81 @@ public abstract class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
return _endPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the local name of the connected channel.</p>
|
||||
*
|
||||
* <p>
|
||||
* This is the host name after the connector is bound and the connection is accepted.
|
||||
* </p>
|
||||
* <p>
|
||||
* Value can be overridden by {@link HttpConfiguration#setLocalAddress(SocketAddress)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note: some connectors are not based on IP networking, and default behavior here will
|
||||
* result in a null return. Use {@link HttpConfiguration#setLocalAddress(SocketAddress)}
|
||||
* to set the value to an acceptable host name.
|
||||
* </p>
|
||||
*
|
||||
* @return the local name, or null
|
||||
*/
|
||||
public String getLocalName()
|
||||
{
|
||||
HttpConfiguration httpConfiguration = getHttpConfiguration();
|
||||
if (httpConfiguration != null)
|
||||
{
|
||||
SocketAddress localAddress = httpConfiguration.getLocalAddress();
|
||||
if (localAddress instanceof InetSocketAddress)
|
||||
return ((InetSocketAddress)localAddress).getHostName();
|
||||
}
|
||||
|
||||
InetSocketAddress local = getLocalAddress();
|
||||
if (local != null)
|
||||
return local.getHostString();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the Local Port of the connected channel.</p>
|
||||
*
|
||||
* <p>
|
||||
* This is the port the connector is bound to and is accepting connections on.
|
||||
* </p>
|
||||
* <p>
|
||||
* Value can be overridden by {@link HttpConfiguration#setLocalAddress(SocketAddress)}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note: some connectors are not based on IP networking, and default behavior here will
|
||||
* result in a value of 0 returned. Use {@link HttpConfiguration#setLocalAddress(SocketAddress)}
|
||||
* to set the value to an acceptable port.
|
||||
* </p>
|
||||
*
|
||||
* @return the local port, or 0 if unspecified
|
||||
*/
|
||||
public int getLocalPort()
|
||||
{
|
||||
HttpConfiguration httpConfiguration = getHttpConfiguration();
|
||||
if (httpConfiguration != null)
|
||||
{
|
||||
SocketAddress localAddress = httpConfiguration.getLocalAddress();
|
||||
if (localAddress instanceof InetSocketAddress)
|
||||
return ((InetSocketAddress)localAddress).getPort();
|
||||
}
|
||||
|
||||
InetSocketAddress local = getLocalAddress();
|
||||
return local == null ? 0 : local.getPort();
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress()
|
||||
{
|
||||
HttpConfiguration httpConfiguration = getHttpConfiguration();
|
||||
if (httpConfiguration != null)
|
||||
{
|
||||
SocketAddress localAddress = httpConfiguration.getLocalAddress();
|
||||
if (localAddress instanceof InetSocketAddress)
|
||||
return ((InetSocketAddress)localAddress);
|
||||
}
|
||||
|
||||
SocketAddress local = _endPoint.getLocalSocketAddress();
|
||||
if (local instanceof InetSocketAddress)
|
||||
return (InetSocketAddress)local;
|
||||
|
@ -341,6 +415,18 @@ public abstract class HttpChannel implements Runnable, HttpOutput.Interceptor
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return return the HttpConfiguration server authority override
|
||||
*/
|
||||
public HostPort getServerAuthority()
|
||||
{
|
||||
HttpConfiguration httpConfiguration = getHttpConfiguration();
|
||||
if (httpConfiguration != null)
|
||||
return httpConfiguration.getServerAuthority();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the associated response has the Expect header set to 100 Continue,
|
||||
* then accessing the input stream indicates that the handler/servlet
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
@ -23,6 +24,7 @@ import org.eclipse.jetty.http.HttpCompliance;
|
|||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
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.annotation.ManagedAttribute;
|
||||
|
@ -75,6 +77,8 @@ public class HttpConfiguration implements Dumpable
|
|||
private CookieCompliance _responseCookieCompliance = CookieCompliance.RFC6265;
|
||||
private boolean _notifyRemoteAsyncErrors = true;
|
||||
private boolean _relativeRedirectAllowed;
|
||||
private HostPort _serverAuthority;
|
||||
private SocketAddress _localAddress;
|
||||
|
||||
/**
|
||||
* <p>An interface that allows a request object to be customized
|
||||
|
@ -145,6 +149,8 @@ public class HttpConfiguration implements Dumpable
|
|||
_notifyRemoteAsyncErrors = config._notifyRemoteAsyncErrors;
|
||||
_relativeRedirectAllowed = config._relativeRedirectAllowed;
|
||||
_uriCompliance = config._uriCompliance;
|
||||
_serverAuthority = config._serverAuthority;
|
||||
_localAddress = config._localAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -651,6 +657,69 @@ public class HttpConfiguration implements Dumpable
|
|||
return _relativeRedirectAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SocketAddress override to be reported as the local address of all connections
|
||||
*
|
||||
* @return Returns the connection local address override or null.
|
||||
*/
|
||||
@ManagedAttribute("Local SocketAddress override")
|
||||
public SocketAddress getLocalAddress()
|
||||
{
|
||||
return _localAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Specify the connection local address used within application API layer
|
||||
* when identifying the local host name/port of a connected endpoint.
|
||||
* </p>
|
||||
* <p>
|
||||
* This allows an override of higher level APIs, such as
|
||||
* {@code ServletRequest.getLocalName()}, {@code ServletRequest.getLocalAddr()},
|
||||
* and {@code ServletRequest.getLocalPort()}.
|
||||
* </p>
|
||||
*
|
||||
* @param localAddress the address to use for host/addr/port, or null to reset to default behavior
|
||||
*/
|
||||
public void setLocalAddress(SocketAddress localAddress)
|
||||
{
|
||||
_localAddress = localAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Server authority override to be used if no authority is provided by a request.
|
||||
*
|
||||
* @return Returns the connection server authority (name/port) or null
|
||||
*/
|
||||
@ManagedAttribute("The server authority if none provided by requests")
|
||||
public HostPort getServerAuthority()
|
||||
{
|
||||
return _serverAuthority;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Specify the connection server authority (name/port) used within application API layer
|
||||
* when identifying the server host name/port of a connected endpoint.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This allows an override of higher level APIs, such as
|
||||
* {@code ServletRequest.getServerName()}, and {@code ServletRequest.getServerPort()}.
|
||||
* </p>
|
||||
*
|
||||
* @param authority the authority host (and optional port), or null to reset to default behavior
|
||||
*/
|
||||
public void setServerAuthority(HostPort authority)
|
||||
{
|
||||
if (authority == null)
|
||||
_serverAuthority = null;
|
||||
else if (!authority.hasHost())
|
||||
throw new IllegalStateException("Server Authority must have host declared");
|
||||
else
|
||||
_serverAuthority = authority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String dump()
|
||||
{
|
||||
|
|
|
@ -22,7 +22,6 @@ import java.io.InputStreamReader;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
@ -420,6 +419,7 @@ public class Request implements HttpServletRequest
|
|||
* A response is being committed for a session,
|
||||
* potentially write the session out before the
|
||||
* client receives the response.
|
||||
*
|
||||
* @param session the session
|
||||
*/
|
||||
private void commitSession(Session session)
|
||||
|
@ -978,22 +978,8 @@ public class Request implements HttpServletRequest
|
|||
@Override
|
||||
public String getLocalAddr()
|
||||
{
|
||||
if (_channel == null)
|
||||
if (_channel != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
String name = InetAddress.getLocalHost().getHostAddress();
|
||||
if (StringUtil.ALL_INTERFACES.equals(name))
|
||||
return null;
|
||||
return formatAddrOrHost(name);
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
LOG.trace("IGNORED", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
InetSocketAddress local = _channel.getLocalAddress();
|
||||
if (local == null)
|
||||
return "";
|
||||
|
@ -1001,40 +987,38 @@ public class Request implements HttpServletRequest
|
|||
String result = address == null
|
||||
? local.getHostString()
|
||||
: address.getHostAddress();
|
||||
|
||||
return formatAddrOrHost(result);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* @see javax.servlet.ServletRequest#getLocalName()
|
||||
*/
|
||||
@Override
|
||||
public String getLocalName()
|
||||
{
|
||||
if (_channel != null)
|
||||
{
|
||||
InetSocketAddress local = _channel.getLocalAddress();
|
||||
if (local != null)
|
||||
return formatAddrOrHost(local.getHostString());
|
||||
String localName = _channel.getLocalName();
|
||||
return formatAddrOrHost(localName);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String name = InetAddress.getLocalHost().getHostName();
|
||||
if (StringUtil.ALL_INTERFACES.equals(name))
|
||||
return null;
|
||||
return formatAddrOrHost(name);
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
LOG.trace("IGNORED", e);
|
||||
}
|
||||
return null;
|
||||
return ""; // not allowed to be null
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalPort()
|
||||
{
|
||||
if (_channel == null)
|
||||
if (_channel != null)
|
||||
{
|
||||
int localPort = _channel.getLocalPort();
|
||||
if (localPort > 0)
|
||||
return localPort;
|
||||
}
|
||||
return 0;
|
||||
InetSocketAddress local = _channel.getLocalAddress();
|
||||
return local == null ? 0 : local.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1321,32 +1305,38 @@ public class Request implements HttpServletRequest
|
|||
@Override
|
||||
public String getServerName()
|
||||
{
|
||||
return _uri == null ? findServerName() : formatAddrOrHost(_uri.getHost());
|
||||
if ((_uri != null) && StringUtil.isNotBlank(_uri.getAuthority()))
|
||||
return formatAddrOrHost(_uri.getHost());
|
||||
else
|
||||
return findServerName();
|
||||
}
|
||||
|
||||
private String findServerName()
|
||||
{
|
||||
if (_channel != null)
|
||||
{
|
||||
HostPort serverAuthority = _channel.getServerAuthority();
|
||||
if (serverAuthority != null)
|
||||
return formatAddrOrHost(serverAuthority.getHost());
|
||||
}
|
||||
|
||||
// Return host from connection
|
||||
String name = getLocalName();
|
||||
if (name != null)
|
||||
return formatAddrOrHost(name);
|
||||
|
||||
// Return the local host
|
||||
try
|
||||
{
|
||||
return formatAddrOrHost(InetAddress.getLocalHost().getHostAddress());
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
LOG.trace("IGNORED", e);
|
||||
}
|
||||
return null;
|
||||
return ""; // not allowed to be null
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerPort()
|
||||
{
|
||||
int port = _uri == null ? -1 : _uri.getPort();
|
||||
int port = -1;
|
||||
|
||||
if ((_uri != null) && StringUtil.isNotBlank(_uri.getAuthority()))
|
||||
port = _uri.getPort();
|
||||
else
|
||||
port = findServerPort();
|
||||
|
||||
// If no port specified, return the default port for the scheme
|
||||
if (port <= 0)
|
||||
|
@ -1358,11 +1348,15 @@ public class Request implements HttpServletRequest
|
|||
|
||||
private int findServerPort()
|
||||
{
|
||||
// Return host from connection
|
||||
if (_channel != null)
|
||||
return getLocalPort();
|
||||
{
|
||||
HostPort serverAuthority = _channel.getServerAuthority();
|
||||
if (serverAuthority != null)
|
||||
return serverAuthority.getPort();
|
||||
}
|
||||
|
||||
return -1;
|
||||
// Return host from connection
|
||||
return getLocalPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -237,6 +237,9 @@ public class DetectorConnectionTest
|
|||
|
||||
assertThat(response, Matchers.containsString("HTTP/1.1 200"));
|
||||
assertThat(response, Matchers.containsString("pathInfo=/path"));
|
||||
assertThat(response, Matchers.containsString("servername=server"));
|
||||
assertThat(response, Matchers.containsString("serverport=80"));
|
||||
assertThat(response, Matchers.containsString("localname=5.6.7.8"));
|
||||
assertThat(response, Matchers.containsString("local=5.6.7.8:222"));
|
||||
assertThat(response, Matchers.containsString("remote=1.2.3.4:111"));
|
||||
}
|
||||
|
|
|
@ -105,6 +105,8 @@ public class DumpHandler extends AbstractHandler
|
|||
writer.write("<pre>\ncontentType=" + request.getContentType() + "\n</pre>\n");
|
||||
writer.write("<pre>\nencoding=" + request.getCharacterEncoding() + "\n</pre>\n");
|
||||
writer.write("<pre>\nservername=" + request.getServerName() + "\n</pre>\n");
|
||||
writer.write("<pre>\nserverport=" + request.getServerPort() + "\n</pre>\n");
|
||||
writer.write("<pre>\nlocalname=" + request.getLocalName() + "\n</pre>\n");
|
||||
writer.write("<pre>\nlocal=" + request.getLocalAddr() + ":" + request.getLocalPort() + "\n</pre>\n");
|
||||
writer.write("<pre>\nremote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\n</pre>\n");
|
||||
writer.write("<h3>Header:</h3><pre>");
|
||||
|
|
|
@ -0,0 +1,766 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.HttpTester;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.util.HostPort;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class HttpConfigurationAuthorityOverrideTest
|
||||
{
|
||||
@Test
|
||||
public void testLocalAuthorityHttp10NoHostDump() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("foo.local.name", 80);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[foo.local.name]"),
|
||||
containsString("ServerPort=[80]"),
|
||||
containsString("LocalAddr=[foo.local.name]"),
|
||||
containsString("LocalName=[foo.local.name]"),
|
||||
containsString("LocalPort=[80]"),
|
||||
containsString("RequestURL=[http://foo.local.name/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp10NoHostRedirect() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("foo.local.name", 80);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.local.name/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp10NotFound() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("foo.local.name", 777);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /bogus HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
// because of the custom error handler, we actually expect a redirect
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.local.name:777/error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp11EmptyHostDump() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("foo.local.name", 80);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[foo.local.name]"),
|
||||
containsString("ServerPort=[80]"),
|
||||
containsString("LocalAddr=[foo.local.name]"),
|
||||
containsString("LocalName=[foo.local.name]"),
|
||||
containsString("LocalPort=[80]"),
|
||||
containsString("RequestURL=[http://foo.local.name/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp11EmptyHostRedirect() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("foo.local.name", 80);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connect: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.local.name/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp11EmptyHostAbsUriDump() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("bar.local.name", 9999);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET mobile:///dump HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[bar.local.name]"),
|
||||
containsString("ServerPort=[9999]"),
|
||||
containsString("LocalAddr=[bar.local.name]"),
|
||||
containsString("LocalName=[bar.local.name]"),
|
||||
containsString("LocalPort=[9999]"),
|
||||
containsString("RequestURL=[mobile://bar.local.name:9999/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp11ValidHostDump() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("zed.local.name", 9999);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: jetty.eclipse.org:8888\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[jetty.eclipse.org]"),
|
||||
containsString("ServerPort=[8888]"),
|
||||
containsString("LocalAddr=[zed.local.name]"),
|
||||
containsString("LocalName=[zed.local.name]"),
|
||||
containsString("LocalPort=[9999]"),
|
||||
containsString("RequestURL=[http://jetty.eclipse.org:8888/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalAuthorityHttp11ValidHostRedirect() throws Exception
|
||||
{
|
||||
InetSocketAddress localAddress = InetSocketAddress.createUnresolved("zed.local.name", 9999);
|
||||
|
||||
try (CloseableServer server = startServer(null, localAddress))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: jetty.eclipse.org:8888\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://jetty.eclipse.org:8888/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerAuthorityNoPortHttp11EmptyHostDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("foo.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[foo.server.authority]"),
|
||||
containsString("ServerPort=[80]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://foo.server.authority/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerAuthorityNoPortHttp11EmptyHostRedirect() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("foo.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connect: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.server.authority/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerAuthorityWithPortHttp11EmptyHostDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("foo.server.authority:7777");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[foo.server.authority]"),
|
||||
containsString("ServerPort=[7777]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://foo.server.authority:7777/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerAuthorityWithPortHttp11EmptyHostRedirect() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("foo.server.authority:7777");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connect: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.server.authority:7777/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityNoPortHttp10NoHostDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("foo.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[foo.server.authority]"),
|
||||
containsString("ServerPort=[80]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://foo.server.authority/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityNoPortHttp10NoHostRedirect() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("foo.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.server.authority/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityNoPortHttp10NotFound() throws Exception
|
||||
{
|
||||
HostPort severUriAuthority = new HostPort("foo.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(severUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /bogus HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
// because of the custom error handler, we actually expect a redirect
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.server.authority/error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityNoPortHttp10PathError() throws Exception
|
||||
{
|
||||
HostPort severUriAuthority = new HostPort("foo.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(severUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /%00 HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.BAD_REQUEST_400));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityNoPortHttp11ValidHostDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("zed.server.authority");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: jetty.eclipse.org:8888\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[jetty.eclipse.org]"),
|
||||
containsString("ServerPort=[8888]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://jetty.eclipse.org:8888/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityNoPortHttp11ValidHostRedirect() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("zed.local.name");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: jetty.eclipse.org:8888\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://jetty.eclipse.org:8888/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityWithPortHttp10NoHostDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("bar.server.authority:9999");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[bar.server.authority]"),
|
||||
containsString("ServerPort=[9999]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://bar.server.authority:9999/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityWithPortHttp10NoHostRedirect() throws Exception
|
||||
{
|
||||
HostPort severUriAuthority = new HostPort("foo.server.authority:9999");
|
||||
|
||||
try (CloseableServer server = startServer(severUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.server.authority:9999/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityWithPortHttp10NotFound() throws Exception
|
||||
{
|
||||
HostPort severUriAuthority = new HostPort("foo.server.authority:7777");
|
||||
|
||||
try (CloseableServer server = startServer(severUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /bogus HTTP/1.0\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
// because of the custom error handler, we actually expect a redirect
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://foo.server.authority:7777/error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityWithPortHttp11ValidHostDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("zed.server.authority:7777");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: jetty.eclipse.org:8888\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[jetty.eclipse.org]"),
|
||||
containsString("ServerPort=[8888]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://jetty.eclipse.org:8888/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityWithPortHttp11EmptyHostAbsUriDump() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("zed.server.authority:7777");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET mobile:///dump HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[zed.server.authority]"),
|
||||
containsString("ServerPort=[7777]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[mobile://zed.server.authority:7777/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServerUriAuthorityWithPortHttp11ValidHostRedirect() throws Exception
|
||||
{
|
||||
HostPort serverUriAuthority = new HostPort("zed.local.name:7777");
|
||||
|
||||
try (CloseableServer server = startServer(serverUriAuthority, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: jetty.eclipse.org:8888\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://jetty.eclipse.org:8888/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsetAuthoritiesHttp11EmptyHostDump() throws Exception
|
||||
{
|
||||
try (CloseableServer server = startServer(null, null))
|
||||
{
|
||||
String rawRequest = "GET /dump HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat("response.status", response.getStatus(), is(200));
|
||||
String responseContent = response.getContent();
|
||||
assertThat("response content", responseContent, allOf(
|
||||
containsString("ServerName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("ServerPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
// expect default locals
|
||||
containsString("LocalAddr=[" + server.getConnectorLocalAddr() + "]"),
|
||||
containsString("LocalName=[" + server.getConnectorLocalName() + "]"),
|
||||
containsString("LocalPort=[" + server.getConnectorLocalPort() + "]"),
|
||||
containsString("RequestURL=[http://" + server.getConnectorLocalName() + ":" + server.getConnectorLocalPort() + "/dump]")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsetAuthoritiesHttp11EmptyHostRedirect() throws Exception
|
||||
{
|
||||
try (CloseableServer server = startServer(null, null))
|
||||
{
|
||||
String rawRequest = "GET /redirect HTTP/1.1\r\n" +
|
||||
"Host: \r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
|
||||
HttpTester.Response response = issueRequest(server, rawRequest);
|
||||
|
||||
assertThat(response.getStatus(), is(HttpStatus.MOVED_TEMPORARILY_302));
|
||||
String location = response.get(HttpHeader.LOCATION);
|
||||
assertThat(location, is("http://" + server.getConnectorLocalName() + ":" + server.getConnectorLocalPort() + "/dump"));
|
||||
}
|
||||
}
|
||||
|
||||
private HttpTester.Response issueRequest(CloseableServer server, String rawRequest) throws Exception
|
||||
{
|
||||
try (Socket socket = new Socket("localhost", server.getConnectorLocalPort());
|
||||
OutputStream output = socket.getOutputStream();
|
||||
InputStream input = socket.getInputStream())
|
||||
{
|
||||
output.write(rawRequest.getBytes(StandardCharsets.UTF_8));
|
||||
output.flush();
|
||||
|
||||
HttpTester.Response response = HttpTester.parseResponse(HttpTester.from(input));
|
||||
assertNotNull(response, "response");
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
private CloseableServer startServer(HostPort serverUriAuthority, InetSocketAddress localAddress) throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
|
||||
HttpConfiguration httpConfiguration = new HttpConfiguration();
|
||||
if (serverUriAuthority != null)
|
||||
httpConfiguration.setServerAuthority(serverUriAuthority);
|
||||
if (localAddress != null)
|
||||
httpConfiguration.setLocalAddress(localAddress);
|
||||
|
||||
ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration));
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
|
||||
HandlerList handlers = new HandlerList();
|
||||
handlers.addHandler(new RedirectHandler());
|
||||
handlers.addHandler(new DumpHandler());
|
||||
handlers.addHandler(new ErrorMsgHandler());
|
||||
server.setHandler(handlers);
|
||||
|
||||
server.setErrorHandler(new RedirectErrorHandler());
|
||||
server.start();
|
||||
|
||||
return new CloseableServer(server, connector);
|
||||
}
|
||||
|
||||
private static class DumpHandler extends AbstractHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
if (target.startsWith("/dump"))
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("text/plain");
|
||||
PrintWriter out = response.getWriter();
|
||||
out.printf("ServerName=[%s]%n", request.getServerName());
|
||||
out.printf("ServerPort=[%d]%n", request.getServerPort());
|
||||
out.printf("LocalName=[%s]%n", request.getLocalName());
|
||||
out.printf("LocalAddr=[%s]%n", request.getLocalAddr());
|
||||
out.printf("LocalPort=[%s]%n", request.getLocalPort());
|
||||
out.printf("RequestURL=[%s]%n", request.getRequestURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class RedirectHandler extends AbstractHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
if (target.startsWith("/redirect"))
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.sendRedirect("/dump");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ErrorMsgHandler extends AbstractHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
if (target.startsWith("/error"))
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("text/plain");
|
||||
response.getWriter().println("Generic Error Page.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RedirectErrorHandler extends ErrorHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
response.sendRedirect("/error");
|
||||
}
|
||||
}
|
||||
|
||||
private static class CloseableServer implements AutoCloseable
|
||||
{
|
||||
private final Server server;
|
||||
private final ServerConnector connector;
|
||||
|
||||
public CloseableServer(Server server, ServerConnector connector)
|
||||
{
|
||||
this.server = Objects.requireNonNull(server, "Server");
|
||||
this.connector = Objects.requireNonNull(connector, "Connector");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception
|
||||
{
|
||||
LifeCycle.stop(this.server);
|
||||
}
|
||||
|
||||
public String getConnectorLocalAddr()
|
||||
{
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
public String getConnectorLocalName()
|
||||
{
|
||||
return HostPort.normalizeHost(getConnectorLocalAddr());
|
||||
}
|
||||
|
||||
public int getConnectorLocalPort()
|
||||
{
|
||||
return this.connector.getLocalPort();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
package org.eclipse.jetty.util;
|
||||
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
||||
/**
|
||||
* <p>Parse an authority string (in the form {@code host:port}) into
|
||||
* {@code host} and {@code port}, handling IPv4 and IPv6 host formats
|
||||
|
@ -99,6 +101,7 @@ public class HostPort
|
|||
*
|
||||
* @return the host
|
||||
*/
|
||||
@ManagedAttribute("host")
|
||||
public String getHost()
|
||||
{
|
||||
return _host;
|
||||
|
@ -109,6 +112,7 @@ public class HostPort
|
|||
*
|
||||
* @return the port
|
||||
*/
|
||||
@ManagedAttribute("port")
|
||||
public int getPort()
|
||||
{
|
||||
return _port;
|
||||
|
@ -125,6 +129,16 @@ public class HostPort
|
|||
return _port > 0 ? _port : defaultPort;
|
||||
}
|
||||
|
||||
public boolean hasHost()
|
||||
{
|
||||
return StringUtil.isNotBlank(_host);
|
||||
}
|
||||
|
||||
public boolean hasPort()
|
||||
{
|
||||
return _port > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue