Merge remote-tracking branch 'eclipse/jetty-10.0.x' into jetty-10.0.x-3494-clientclosetest
Signed-off-by: lachan-roberts <lachlan@webtide.com>
This commit is contained in:
commit
002ecf526d
|
@ -97,7 +97,7 @@ def mavenBuild(jdk, cmdline, mvnName, junitPublishDisabled) {
|
|||
mavenOpts: mavenOpts,
|
||||
mavenLocalRepo: localRepo) {
|
||||
// Some common Maven command line + provided command line
|
||||
sh "mvn -V -B -T3 -e -fae -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + env.JENKINS_HOME
|
||||
sh "mvn -Pci -V -B -T3 -e -fae -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + env.JENKINS_HOME
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -116,7 +115,8 @@ public class FastFileServer
|
|||
}
|
||||
String listing = Resource.newResource(file).getListHTML(
|
||||
request.getRequestURI(),
|
||||
request.getPathInfo().lastIndexOf("/") > 0);
|
||||
request.getPathInfo().lastIndexOf("/") > 0,
|
||||
request.getQueryString());
|
||||
response.setContentType("text/html; charset=utf-8");
|
||||
response.getWriter().println(listing);
|
||||
return;
|
||||
|
|
|
@ -60,10 +60,6 @@ import org.eclipse.jetty.servlet.ServletHolder;
|
|||
import org.eclipse.jetty.servlets.PushCacheFilter;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
public class Http2Server
|
||||
{
|
||||
public static void main(String... args) throws Exception
|
||||
|
@ -102,7 +98,7 @@ public class Http2Server
|
|||
String jetty_distro = System.getProperty("jetty.distro","../../jetty-distribution/target/distribution");
|
||||
if (!new File(jetty_distro).exists())
|
||||
jetty_distro = "jetty-distribution/target/distribution";
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(jetty_distro + "/demo-base/etc/keystore");
|
||||
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
|
||||
|
|
|
@ -139,7 +139,7 @@ public class LikeJettyXml
|
|||
|
||||
// === jetty-https.xml ===
|
||||
// SSL Context Factory
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(jetty_home + "/../../../jetty-server/src/test/config/etc/keystore");
|
||||
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
|
||||
|
|
|
@ -20,9 +20,7 @@ package org.eclipse.jetty.embedded;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.security.Security;
|
||||
|
||||
import org.conscrypt.OpenSSLProvider;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
|
@ -89,7 +87,7 @@ public class ManyConnectors
|
|||
// including things like choosing the particular certificate out of a
|
||||
// keystore to be used.
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.jetty.client.api.ContentResponse;
|
|||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -60,24 +61,35 @@ public class ConscryptHTTP2ServerTest
|
|||
|
||||
private Server server = new Server();
|
||||
|
||||
private SslContextFactory newSslContextFactory()
|
||||
private SslContextFactory.Server newServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private SslContextFactory.Client newClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private void configureSslContextFactory(SslContextFactory sslContextFactory)
|
||||
{
|
||||
Path path = Paths.get("src", "test", "resources");
|
||||
File keys = path.resolve("keystore").toFile();
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setTrustStorePath(keys.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
|
||||
sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setProvider("Conscrypt");
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
if (JavaVersion.VERSION.getPlatform() < 9)
|
||||
{
|
||||
// Conscrypt enables TLSv1.3 by default but it's not supported in Java 8.
|
||||
sslContextFactory.addExcludeProtocols("TLSv1.3");
|
||||
}
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
|
@ -94,7 +106,7 @@ public class ConscryptHTTP2ServerTest
|
|||
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig);
|
||||
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
|
||||
alpn.setDefaultProtocol(http.getProtocol());
|
||||
SslConnectionFactory ssl = new SslConnectionFactory(newSslContextFactory(), alpn.getProtocol());
|
||||
SslConnectionFactory ssl = new SslConnectionFactory(newServerSslContextFactory(), alpn.getProtocol());
|
||||
|
||||
ServerConnector http2Connector = new ServerConnector(server, ssl, alpn, h2, http);
|
||||
http2Connector.setPort(0);
|
||||
|
@ -123,8 +135,10 @@ public class ConscryptHTTP2ServerTest
|
|||
@Test
|
||||
public void testSimpleRequest() throws Exception
|
||||
{
|
||||
HTTP2Client h2Client = new HTTP2Client();
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(h2Client), newSslContextFactory());
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSslContextFactory(newClientSslContextFactory());
|
||||
HTTP2Client h2Client = new HTTP2Client(clientConnector);
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(h2Client));
|
||||
client.start();
|
||||
try
|
||||
{
|
||||
|
|
|
@ -59,7 +59,7 @@ public class JDK9ALPNTest
|
|||
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpConfiguration);
|
||||
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
|
||||
alpn.setDefaultProtocol(h1.getProtocol());
|
||||
connector = new ServerConnector(server, newSslContextFactory(), alpn, h1, h2);
|
||||
connector = new ServerConnector(server, newServerSslContextFactory(), alpn, h1, h2);
|
||||
server.addConnector(connector);
|
||||
server.setHandler(handler);
|
||||
server.start();
|
||||
|
@ -72,9 +72,9 @@ public class JDK9ALPNTest
|
|||
server.stop();
|
||||
}
|
||||
|
||||
private SslContextFactory newSslContextFactory()
|
||||
private SslContextFactory.Server newServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
|
||||
|
@ -95,7 +95,7 @@ public class JDK9ALPNTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory(true);
|
||||
SslContextFactory sslContextFactory = new SslContextFactory.Client(true);
|
||||
sslContextFactory.start();
|
||||
SSLContext sslContext = sslContextFactory.getSslContext();
|
||||
try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost", connector.getLocalPort()))
|
||||
|
@ -137,7 +137,7 @@ public class JDK9ALPNTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory(true);
|
||||
SslContextFactory sslContextFactory = new SslContextFactory.Client(true);
|
||||
sslContextFactory.start();
|
||||
SSLContext sslContext = sslContextFactory.getSslContext();
|
||||
try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost", connector.getLocalPort()))
|
||||
|
|
|
@ -45,7 +45,7 @@ public class JDK9HTTP2Server
|
|||
httpsConfig.setSendServerVersion(true);
|
||||
httpsConfig.addCustomizer(new SecureRequestCustomizer());
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -217,6 +218,8 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
|
|||
path = request.getPath();
|
||||
}
|
||||
Request newRequest = client.copyRequest(request, requestURI);
|
||||
// Disable the timeout so that only the one from the initial request applies.
|
||||
newRequest.timeout(0, TimeUnit.MILLISECONDS);
|
||||
if (path != null)
|
||||
newRequest.path(path);
|
||||
|
||||
|
|
|
@ -159,47 +159,11 @@ public class HttpClient extends ContainerLifeCycle
|
|||
this(new HttpClientTransportOverHTTP());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HttpClient instance that can perform HTTP requests to non-TLS and TLS destinations
|
||||
* (that is, both requests with the "http" scheme and with the "https" scheme).
|
||||
*
|
||||
* @param sslContextFactory the {@link SslContextFactory} that manages TLS encryption
|
||||
* @see #getSslContextFactory()
|
||||
* @deprecated configure the SslContextFactory on the transport's {@link ClientConnector}
|
||||
*/
|
||||
@Deprecated
|
||||
public HttpClient(SslContextFactory sslContextFactory)
|
||||
{
|
||||
this(new HttpClientTransportOverHTTP(), sslContextFactory);
|
||||
}
|
||||
|
||||
public HttpClient(HttpClientTransport transport)
|
||||
{
|
||||
this(null, transport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a HttpClient instance that can perform HTTP requests with the given transport
|
||||
* to non-TLS and TLS destinations (that is, both requests with the "http" scheme and with
|
||||
* the "https" scheme).
|
||||
*
|
||||
* @param transport the transport that sends and receives HTTP requests and responses
|
||||
* @param sslContextFactory the {@link SslContextFactory} that manages TLS encryption
|
||||
* @deprecated configure the SslContextFactory on the transport's {@link ClientConnector}
|
||||
*/
|
||||
@Deprecated
|
||||
public HttpClient(HttpClientTransport transport, SslContextFactory sslContextFactory)
|
||||
{
|
||||
this(sslContextFactory, transport);
|
||||
}
|
||||
|
||||
private HttpClient(SslContextFactory sslContextFactory, HttpClientTransport transport)
|
||||
{
|
||||
this.transport = Objects.requireNonNull(transport);
|
||||
addBean(transport);
|
||||
this.connector = ((AbstractHttpClientTransport)transport).getBean(ClientConnector.class);
|
||||
if (sslContextFactory != null)
|
||||
connector.setSslContextFactory(sslContextFactory);
|
||||
addBean(handlers);
|
||||
addBean(decoderFactories);
|
||||
}
|
||||
|
@ -217,9 +181,8 @@ public class HttpClient extends ContainerLifeCycle
|
|||
|
||||
/**
|
||||
* @return the {@link SslContextFactory} that manages TLS encryption
|
||||
* @see #HttpClient(SslContextFactory)
|
||||
*/
|
||||
public SslContextFactory getSslContextFactory()
|
||||
public SslContextFactory.Client getSslContextFactory()
|
||||
{
|
||||
return connector.getSslContextFactory();
|
||||
}
|
||||
|
@ -955,7 +918,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the max number of HTTP redirects that are followed
|
||||
* @return the max number of HTTP redirects that are followed in a conversation
|
||||
* @see #setMaxRedirects(int)
|
||||
*/
|
||||
public int getMaxRedirects()
|
||||
|
@ -964,7 +927,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
/**
|
||||
* @param maxRedirects the max number of HTTP redirects that are followed
|
||||
* @param maxRedirects the max number of HTTP redirects that are followed in a conversation, or -1 for unlimited redirects
|
||||
* @see #setFollowRedirects(boolean)
|
||||
*/
|
||||
public void setMaxRedirects(int maxRedirects)
|
||||
|
|
|
@ -25,9 +25,13 @@ import java.util.concurrent.ConcurrentLinkedDeque;
|
|||
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
public class HttpConversation extends AttributesMap
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(HttpConversation.class);
|
||||
|
||||
private final Deque<HttpExchange> exchanges = new ConcurrentLinkedDeque<>();
|
||||
private volatile List<Response.ResponseListener> listeners;
|
||||
|
||||
|
@ -118,6 +122,7 @@ public class HttpConversation extends AttributesMap
|
|||
HttpExchange lastExchange = exchanges.peekLast();
|
||||
if (firstExchange == lastExchange)
|
||||
{
|
||||
// We don't have a conversation, just a single request.
|
||||
if (overrideListener != null)
|
||||
listeners.add(overrideListener);
|
||||
else
|
||||
|
@ -125,13 +130,16 @@ public class HttpConversation extends AttributesMap
|
|||
}
|
||||
else
|
||||
{
|
||||
// Order is important, we want to notify the last exchange first
|
||||
// We have a conversation (e.g. redirect, authentication).
|
||||
// Order is important, we want to notify the last exchange first.
|
||||
listeners.addAll(lastExchange.getResponseListeners());
|
||||
if (overrideListener != null)
|
||||
listeners.add(overrideListener);
|
||||
else
|
||||
listeners.addAll(firstExchange.getResponseListeners());
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Exchanges in conversation {}, override={}, listeners={}", exchanges.size(), overrideListener, listeners);
|
||||
this.listeners = listeners;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,12 +72,6 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
private final TimeoutTask timeout;
|
||||
private ConnectionPool connectionPool;
|
||||
|
||||
@Deprecated
|
||||
public HttpDestination(HttpClient client, Origin origin)
|
||||
{
|
||||
this(client, new Key(origin, null));
|
||||
}
|
||||
|
||||
public HttpDestination(HttpClient client, Key key)
|
||||
{
|
||||
this(client, key, Function.identity());
|
||||
|
@ -683,7 +677,11 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
}
|
||||
}
|
||||
|
||||
// The TimeoutTask that expires when the next check of expiry is needed
|
||||
/**
|
||||
* This class enforces the total timeout for exchanges that are still in the queue.
|
||||
* The total timeout for exchanges that are not in the destination queue is enforced
|
||||
* by {@link HttpChannel}.
|
||||
*/
|
||||
private class TimeoutTask extends CyclicTimeout
|
||||
{
|
||||
private final AtomicLong nextTimeout = new AtomicLong(Long.MAX_VALUE);
|
||||
|
@ -696,6 +694,9 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
@Override
|
||||
public void onTimeoutExpired()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} timeout expired", this);
|
||||
|
||||
nextTimeout.set(Long.MAX_VALUE);
|
||||
long now = System.nanoTime();
|
||||
long nextExpiresAt = Long.MAX_VALUE;
|
||||
|
@ -728,12 +729,16 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
if (timeoutAt != expiresAt)
|
||||
{
|
||||
long delay = expiresAt - System.nanoTime();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Scheduled timeout in {} ms", TimeUnit.NANOSECONDS.toMillis(delay));
|
||||
if (delay <= 0)
|
||||
{
|
||||
onTimeoutExpired();
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule(delay, TimeUnit.NANOSECONDS);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} scheduled timeout in {} ms", this, TimeUnit.NANOSECONDS.toMillis(delay));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.net.URISyntaxException;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -61,10 +62,10 @@ public class HttpRedirector
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(HttpRedirector.class);
|
||||
private static final String SCHEME_REGEXP = "(^https?)";
|
||||
private static final String AUTHORITY_REGEXP = "([^/\\?#]+)";
|
||||
private static final String AUTHORITY_REGEXP = "([^/?#]+)";
|
||||
// The location may be relative so the scheme://authority part may be missing
|
||||
private static final String DESTINATION_REGEXP = "(" + SCHEME_REGEXP + "://" + AUTHORITY_REGEXP + ")?";
|
||||
private static final String PATH_REGEXP = "([^\\?#]*)";
|
||||
private static final String PATH_REGEXP = "([^?#]*)";
|
||||
private static final String QUERY_REGEXP = "([^#]*)";
|
||||
private static final String FRAGMENT_REGEXP = "(.*)";
|
||||
private static final Pattern URI_PATTERN = Pattern.compile(DESTINATION_REGEXP + PATH_REGEXP + QUERY_REGEXP + FRAGMENT_REGEXP);
|
||||
|
@ -101,11 +102,11 @@ public class HttpRedirector
|
|||
/**
|
||||
* Redirects the given {@code response}, blocking until the redirect is complete.
|
||||
*
|
||||
* @param request the original request that triggered the redirect
|
||||
* @param request the original request that triggered the redirect
|
||||
* @param response the response to the original request
|
||||
* @return a {@link Result} object containing the request to the redirected location and its response
|
||||
* @throws InterruptedException if the thread is interrupted while waiting for the redirect to complete
|
||||
* @throws ExecutionException if the redirect failed
|
||||
* @throws ExecutionException if the redirect failed
|
||||
* @see #redirect(Request, Response, Response.CompleteListener)
|
||||
*/
|
||||
public Result redirect(Request request, Response response) throws InterruptedException, ExecutionException
|
||||
|
@ -144,7 +145,7 @@ public class HttpRedirector
|
|||
/**
|
||||
* Redirects the given {@code response} asynchronously.
|
||||
*
|
||||
* @param request the original request that triggered the redirect
|
||||
* @param request the original request that triggered the redirect
|
||||
* @param response the response to the original request
|
||||
* @param listener the listener that receives response events
|
||||
* @return the request to the redirected location
|
||||
|
@ -292,7 +293,8 @@ public class HttpRedirector
|
|||
Integer redirects = (Integer)conversation.getAttribute(ATTRIBUTE);
|
||||
if (redirects == null)
|
||||
redirects = 0;
|
||||
if (redirects < client.getMaxRedirects())
|
||||
int maxRedirects = client.getMaxRedirects();
|
||||
if (maxRedirects < 0 || redirects < maxRedirects)
|
||||
{
|
||||
++redirects;
|
||||
conversation.setAttribute(ATTRIBUTE, redirects);
|
||||
|
@ -310,19 +312,17 @@ public class HttpRedirector
|
|||
try
|
||||
{
|
||||
Request redirect = client.copyRequest(httpRequest, location);
|
||||
// Disable the timeout so that only the one from the initial request applies.
|
||||
redirect.timeout(0, TimeUnit.MILLISECONDS);
|
||||
|
||||
// Use given method
|
||||
redirect.method(method);
|
||||
|
||||
redirect.onRequestBegin(new Request.BeginListener()
|
||||
redirect.onRequestBegin(request ->
|
||||
{
|
||||
@Override
|
||||
public void onBegin(Request redirect)
|
||||
{
|
||||
Throwable cause = httpRequest.getAbortCause();
|
||||
if (cause != null)
|
||||
redirect.abort(cause);
|
||||
}
|
||||
Throwable cause = httpRequest.getAbortCause();
|
||||
if (cause != null)
|
||||
request.abort(cause);
|
||||
});
|
||||
|
||||
redirect.send(listener);
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.eclipse.jetty.client.api.Request;
|
|||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.io.CyclicTimeout;
|
||||
import org.eclipse.jetty.util.component.Destroyable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
|
@ -47,7 +46,7 @@ public class TimeoutCompleteListener extends CyclicTimeout implements Response.C
|
|||
{
|
||||
Request request = this.request.getAndSet(null);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Total timeout {} ms elapsed for {}", request.getTimeout(), request);
|
||||
LOG.debug("Total timeout {} ms elapsed for {} on {}", request.getTimeout(), request, this);
|
||||
if (request != null)
|
||||
request.abort(new TimeoutException("Total timeout " + request.getTimeout() + " ms elapsed"));
|
||||
}
|
||||
|
@ -60,7 +59,7 @@ public class TimeoutCompleteListener extends CyclicTimeout implements Response.C
|
|||
{
|
||||
boolean cancelled = cancel();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Cancelled ({}) timeout for {}", cancelled, request);
|
||||
LOG.debug("Cancelled ({}) timeout for {} on {}", cancelled, request, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,12 +68,16 @@ public class TimeoutCompleteListener extends CyclicTimeout implements Response.C
|
|||
if (this.request.compareAndSet(null, request))
|
||||
{
|
||||
long delay = timeoutAt - System.nanoTime();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Scheduled timeout in {} ms for {}", TimeUnit.NANOSECONDS.toMillis(delay), request);
|
||||
if (delay <= 0)
|
||||
{
|
||||
onTimeoutExpired();
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule(delay, TimeUnit.NANOSECONDS);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Scheduled timeout in {} ms for {} on {}", TimeUnit.NANOSECONDS.toMillis(delay), request, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,12 +261,14 @@ public interface Request
|
|||
Request idleTimeout(long timeout, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* @return the total timeout for this request, in milliseconds
|
||||
* @return the total timeout for this request, in milliseconds;
|
||||
* zero or negative if the timeout is disabled
|
||||
*/
|
||||
long getTimeout();
|
||||
|
||||
/**
|
||||
* @param timeout the total timeout for the request/response conversation
|
||||
* @param timeout the total timeout for the request/response conversation;
|
||||
* use zero or a negative value to disable the timeout
|
||||
* @param unit the timeout unit
|
||||
* @return this request object
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
|
@ -58,7 +59,7 @@ public abstract class AbstractHttpClientServerTest
|
|||
serverThreads.setName("server");
|
||||
server = new Server(serverThreads);
|
||||
}
|
||||
connector = new ServerConnector(server, scenario.newSslContextFactory());
|
||||
connector = new ServerConnector(server, scenario.newServerSslContextFactory());
|
||||
connector.setPort(0);
|
||||
server.addConnector(connector);
|
||||
server.setHandler(handler);
|
||||
|
@ -67,30 +68,30 @@ public abstract class AbstractHttpClientServerTest
|
|||
|
||||
protected void startClient(final Scenario scenario) throws Exception
|
||||
{
|
||||
startClient(scenario, null,null);
|
||||
startClient(scenario, null);
|
||||
}
|
||||
|
||||
protected void startClient(final Scenario scenario, HttpClientTransport transport, Consumer<HttpClient> config) throws Exception
|
||||
protected void startClient(final Scenario scenario, Consumer<HttpClient> config) throws Exception
|
||||
{
|
||||
if (transport==null)
|
||||
transport = new HttpClientTransportOverHTTP(1);
|
||||
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
clientConnector.setSslContextFactory(scenario.newClientSslContextFactory());
|
||||
HttpClientTransport transport = new HttpClientTransportOverHTTP(clientConnector);
|
||||
QueuedThreadPool executor = new QueuedThreadPool();
|
||||
executor.setName("client");
|
||||
clientConnector.setExecutor(executor);
|
||||
Scheduler scheduler = new ScheduledExecutorScheduler("client-scheduler", false);
|
||||
client = newHttpClient(scenario, transport);
|
||||
client.setExecutor(executor);
|
||||
client.setScheduler(scheduler);
|
||||
clientConnector.setScheduler(scheduler);
|
||||
client = newHttpClient(transport);
|
||||
client.setSocketAddressResolver(new SocketAddressResolver.Sync());
|
||||
if (config!=null)
|
||||
if (config != null)
|
||||
config.accept(client);
|
||||
|
||||
client.start();
|
||||
}
|
||||
|
||||
public HttpClient newHttpClient(Scenario scenario, HttpClientTransport transport)
|
||||
public HttpClient newHttpClient(HttpClientTransport transport)
|
||||
{
|
||||
return new HttpClient(transport, scenario.newSslContextFactory());
|
||||
return new HttpClient(transport);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
@ -113,9 +114,10 @@ public abstract class AbstractHttpClientServerTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class ScenarioProvider implements ArgumentsProvider {
|
||||
public static class ScenarioProvider implements ArgumentsProvider
|
||||
{
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context)
|
||||
{
|
||||
return Stream.of(
|
||||
new NormalScenario(),
|
||||
|
@ -125,9 +127,10 @@ public abstract class AbstractHttpClientServerTest
|
|||
}
|
||||
}
|
||||
|
||||
public static class NonSslScenarioProvider implements ArgumentsProvider {
|
||||
public static class NonSslScenarioProvider implements ArgumentsProvider
|
||||
{
|
||||
@Override
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception
|
||||
public Stream<? extends Arguments> provideArguments(ExtensionContext context)
|
||||
{
|
||||
return Stream.of(
|
||||
new NormalScenario()
|
||||
|
@ -138,12 +141,27 @@ public abstract class AbstractHttpClientServerTest
|
|||
|
||||
public interface Scenario
|
||||
{
|
||||
default SslContextFactory newSslContextFactory() { return null; }
|
||||
SslContextFactory.Client newClientSslContextFactory();
|
||||
|
||||
SslContextFactory.Server newServerSslContextFactory();
|
||||
|
||||
String getScheme();
|
||||
}
|
||||
|
||||
public static class NormalScenario implements Scenario
|
||||
{
|
||||
@Override
|
||||
public SslContextFactory.Client newClientSslContextFactory()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SslContextFactory.Server newServerSslContextFactory()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScheme()
|
||||
{
|
||||
|
@ -160,15 +178,27 @@ public abstract class AbstractHttpClientServerTest
|
|||
public static class SslScenario implements Scenario
|
||||
{
|
||||
@Override
|
||||
public SslContextFactory newSslContextFactory()
|
||||
public SslContextFactory.Client newClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Client result = new SslContextFactory.Client();
|
||||
result.setEndpointIdentificationAlgorithm(null);
|
||||
configure(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SslContextFactory.Server newServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Server result = new SslContextFactory.Server();
|
||||
configure(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void configure(SslContextFactory ssl)
|
||||
{
|
||||
Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore.jks");
|
||||
|
||||
SslContextFactory ssl = new SslContextFactory();
|
||||
ssl.setEndpointIdentificationAlgorithm("");
|
||||
ssl.setKeyStorePath(keystorePath.toString());
|
||||
ssl.setKeyStorePassword("storepwd");
|
||||
return ssl;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -31,7 +28,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -53,6 +49,9 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@Disabled // Disabled by @gregw on issue #2540 - commit 621b946b10884e7308eacca241dcf8b5d6f6cff2
|
||||
public class ConnectionPoolTest
|
||||
{
|
||||
|
@ -83,7 +82,7 @@ public class ConnectionPoolTest
|
|||
transport.setConnectionPoolFactory(factory);
|
||||
server.start();
|
||||
|
||||
client = new HttpClient(transport, null);
|
||||
client = new HttpClient(transport);
|
||||
client.start();
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,7 @@ public class ConnectionPoolTest
|
|||
start(factory, new EmptyServerHandler()
|
||||
{
|
||||
@Override
|
||||
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
switch (HttpMethod.fromString(request.getMethod()))
|
||||
{
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -30,12 +26,15 @@ import org.eclipse.jetty.client.api.ContentResponse;
|
|||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
@Disabled
|
||||
public class ExternalSiteTest
|
||||
{
|
||||
|
@ -44,7 +43,7 @@ public class ExternalSiteTest
|
|||
@BeforeEach
|
||||
public void prepare() throws Exception
|
||||
{
|
||||
client = new HttpClient(new SslContextFactory());
|
||||
client = new HttpClient();
|
||||
client.start();
|
||||
}
|
||||
|
||||
|
@ -64,28 +63,20 @@ public class ExternalSiteTest
|
|||
assumeCanConnectTo(host, port);
|
||||
|
||||
final CountDownLatch latch1 = new CountDownLatch(1);
|
||||
client.newRequest(host, port).send(new Response.CompleteListener()
|
||||
client.newRequest(host, port).send(result ->
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
{
|
||||
if (!result.isFailed() && result.getResponse().getStatus() == 200)
|
||||
latch1.countDown();
|
||||
}
|
||||
if (!result.isFailed() && result.getResponse().getStatus() == 200)
|
||||
latch1.countDown();
|
||||
});
|
||||
assertTrue(latch1.await(10, TimeUnit.SECONDS));
|
||||
|
||||
// Try again the same URI, but without specifying the port
|
||||
final CountDownLatch latch2 = new CountDownLatch(1);
|
||||
client.newRequest("http://" + host).send(new Response.CompleteListener()
|
||||
client.newRequest("http://" + host).send(result ->
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
{
|
||||
assertTrue(result.isSucceeded());
|
||||
assertEquals(200, result.getResponse().getStatus());
|
||||
latch2.countDown();
|
||||
}
|
||||
assertTrue(result.isSucceeded());
|
||||
assertEquals(200, result.getResponse().getStatus());
|
||||
latch2.countDown();
|
||||
});
|
||||
assertTrue(latch2.await(10, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -94,7 +85,7 @@ public class ExternalSiteTest
|
|||
public void testExternalSSLSite() throws Exception
|
||||
{
|
||||
client.stop();
|
||||
client = new HttpClient(new SslContextFactory());
|
||||
client = new HttpClient();
|
||||
client.start();
|
||||
|
||||
String host = "api-3t.paypal.com";
|
||||
|
@ -104,14 +95,10 @@ public class ExternalSiteTest
|
|||
assumeCanConnectTo(host, port);
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
client.newRequest(host, port).scheme("https").path("/nvp").send(new Response.CompleteListener()
|
||||
client.newRequest(host, port).scheme("https").path("/nvp").send(result ->
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
{
|
||||
if (result.isSucceeded() && result.getResponse().getStatus() == 200)
|
||||
latch.countDown();
|
||||
}
|
||||
if (result.isSucceeded() && result.getResponse().getStatus() == 200)
|
||||
latch.countDown();
|
||||
});
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -129,14 +116,7 @@ public class ExternalSiteTest
|
|||
{
|
||||
final CountDownLatch latch = new CountDownLatch(3);
|
||||
client.newRequest(host, port)
|
||||
.onResponseFailure(new Response.FailureListener()
|
||||
{
|
||||
@Override
|
||||
public void onFailure(Response response, Throwable failure)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
})
|
||||
.onResponseFailure((response, failure) -> latch.countDown())
|
||||
.send(new Response.Listener.Adapter()
|
||||
{
|
||||
@Override
|
||||
|
@ -180,7 +160,7 @@ public class ExternalSiteTest
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
assumeTrue(x == null, "Unable to connect");
|
||||
assumeTrue(false, "Unable to connect");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,19 +18,16 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -40,11 +37,14 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* This test class runs tests to make sure that hostname verification (http://www.ietf.org/rfc/rfc2818.txt
|
||||
* section 3.1) is configurable in SslContextFactory and works as expected.
|
||||
|
@ -52,7 +52,7 @@ import org.junit.jupiter.api.Test;
|
|||
@Disabled
|
||||
public class HostnameVerificationTest
|
||||
{
|
||||
private SslContextFactory clientSslContextFactory = new SslContextFactory();
|
||||
private SslContextFactory.Client clientSslContextFactory = new SslContextFactory.Client();
|
||||
private Server server;
|
||||
private HttpClient client;
|
||||
private NetworkConnector connector;
|
||||
|
@ -64,7 +64,7 @@ public class HostnameVerificationTest
|
|||
serverThreads.setName("server");
|
||||
server = new Server(serverThreads);
|
||||
|
||||
SslContextFactory serverSslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server serverSslContextFactory = new SslContextFactory.Server();
|
||||
serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
serverSslContextFactory.setKeyStorePassword("storepwd");
|
||||
connector = new ServerConnector(server, serverSslContextFactory);
|
||||
|
@ -72,7 +72,7 @@ public class HostnameVerificationTest
|
|||
server.setHandler(new DefaultHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.getWriter().write("foobar");
|
||||
|
@ -80,14 +80,19 @@ public class HostnameVerificationTest
|
|||
});
|
||||
server.start();
|
||||
|
||||
// keystore contains a hostname which doesn't match localhost
|
||||
// The keystore contains a hostname which doesn't match localhost
|
||||
clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
clientSslContextFactory.setKeyStorePassword("storepwd");
|
||||
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
clientConnector.setSslContextFactory(clientSslContextFactory);
|
||||
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
client = new HttpClient(clientSslContextFactory);
|
||||
client.setExecutor(clientThreads);
|
||||
clientConnector.setExecutor(clientThreads);
|
||||
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
client.start();
|
||||
}
|
||||
|
||||
|
@ -112,9 +117,7 @@ public class HostnameVerificationTest
|
|||
clientSslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
String uri = "https://localhost:" + connector.getLocalPort() + "/";
|
||||
|
||||
ExecutionException x = assertThrows(ExecutionException.class, ()->{
|
||||
client.GET(uri);
|
||||
});
|
||||
ExecutionException x = assertThrows(ExecutionException.class, ()-> client.GET(uri));
|
||||
Throwable cause = x.getCause();
|
||||
assertThat(cause, Matchers.instanceOf(SSLHandshakeException.class));
|
||||
Throwable root = cause.getCause().getCause();
|
||||
|
|
|
@ -44,9 +44,11 @@ import org.eclipse.jetty.client.api.Request;
|
|||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Response.Listener;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.AbstractAuthentication;
|
||||
import org.eclipse.jetty.client.util.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.util.DeferredContentProvider;
|
||||
import org.eclipse.jetty.client.util.DigestAuthentication;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.security.Authenticator;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
|
@ -57,7 +59,6 @@ import org.eclipse.jetty.security.authentication.BasicAuthenticator;
|
|||
import org.eclipse.jetty.security.authentication.DigestAuthenticator;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
|
@ -67,6 +68,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
import static org.eclipse.jetty.client.api.Authentication.ANY_REALM;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalToIgnoringCase;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -137,7 +139,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
startBasic(scenario, new EmptyServerHandler());
|
||||
URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort());
|
||||
test_Authentication(scenario, new BasicAuthentication(uri, Authentication.ANY_REALM, "basic", "basic"));
|
||||
test_Authentication(scenario, new BasicAuthentication(uri, ANY_REALM, "basic", "basic"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -155,7 +157,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
startDigest(scenario, new EmptyServerHandler());
|
||||
URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort());
|
||||
test_Authentication(scenario, new DigestAuthentication(uri, Authentication.ANY_REALM, "digest", "digest"));
|
||||
test_Authentication(scenario, new DigestAuthentication(uri, ANY_REALM, "digest", "digest"));
|
||||
}
|
||||
|
||||
private void test_Authentication(final Scenario scenario, Authentication authentication) throws Exception
|
||||
|
@ -227,16 +229,19 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void test_BasicAuthentication_ThenRedirect(Scenario scenario) throws Exception
|
||||
{
|
||||
startBasic(scenario, new AbstractHandler()
|
||||
startBasic(scenario, new EmptyServerHandler()
|
||||
{
|
||||
private final AtomicInteger requests = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
if (requests.incrementAndGet() == 1)
|
||||
response.sendRedirect(URIUtil.newURI(scenario.getScheme(), request.getServerName(), request.getServerPort(), request.getRequestURI(), null));
|
||||
int r = requests.incrementAndGet();
|
||||
if (r == 1)
|
||||
{
|
||||
String path = request.getRequestURI() + "/" + r;
|
||||
response.sendRedirect(URIUtil.newURI(scenario.getScheme(), request.getServerName(), request.getServerPort(), path, null));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -269,12 +274,11 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void test_Redirect_ThenBasicAuthentication(Scenario scenario) throws Exception
|
||||
{
|
||||
startBasic(scenario, new AbstractHandler()
|
||||
startBasic(scenario, new EmptyServerHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
if (request.getRequestURI().endsWith("/redirect"))
|
||||
response.sendRedirect(URIUtil.newURI(scenario.getScheme(), request.getServerName(), request.getServerPort(), "/secure", null));
|
||||
}
|
||||
|
@ -571,61 +575,57 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
assertTrue(resultLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
private static class GeneratingContentProvider implements ContentProvider
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void test_InfiniteAuthentication(Scenario scenario) throws Exception
|
||||
{
|
||||
private static final ByteBuffer DONE = ByteBuffer.allocate(0);
|
||||
|
||||
private final IntFunction<ByteBuffer> generator;
|
||||
|
||||
private GeneratingContentProvider(IntFunction<ByteBuffer> generator)
|
||||
String authType = "Authenticate";
|
||||
start(scenario, new EmptyServerHandler()
|
||||
{
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReproducible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ByteBuffer> iterator()
|
||||
{
|
||||
return new Iterator<ByteBuffer>()
|
||||
@Override
|
||||
protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
private int index;
|
||||
public ByteBuffer current;
|
||||
// Always reply with a 401 to see if the client
|
||||
// can handle an infinite authentication loop.
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED_401);
|
||||
response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), authType);
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
public boolean hasNext()
|
||||
AuthenticationStore authenticationStore = client.getAuthenticationStore();
|
||||
URI uri = URI.create(scenario.getScheme() + "://localhost:" + connector.getLocalPort());
|
||||
authenticationStore.addAuthentication(new AbstractAuthentication(uri, Authentication.ANY_REALM)
|
||||
{
|
||||
@Override
|
||||
public String getType()
|
||||
{
|
||||
return authType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result authenticate(Request request, ContentResponse response, HeaderInfo headerInfo, Attributes context)
|
||||
{
|
||||
return new Result()
|
||||
{
|
||||
if (current == null)
|
||||
@Override
|
||||
public URI getURI()
|
||||
{
|
||||
current = generator.apply(index++);
|
||||
if (current == null)
|
||||
current = DONE;
|
||||
return uri;
|
||||
}
|
||||
return current != DONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer next()
|
||||
{
|
||||
ByteBuffer result = current;
|
||||
current = null;
|
||||
if (result == null)
|
||||
throw new NoSuchElementException();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public void apply(Request request)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.send();
|
||||
|
||||
assertEquals(HttpStatus.UNAUTHORIZED_401, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -801,4 +801,61 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
assertEquals("thermostat", headerInfo.getParameter("realm"));
|
||||
assertEquals(headerInfo.getParameter("nonce"), "1523430383=");
|
||||
}
|
||||
|
||||
private static class GeneratingContentProvider implements ContentProvider
|
||||
{
|
||||
private static final ByteBuffer DONE = ByteBuffer.allocate(0);
|
||||
|
||||
private final IntFunction<ByteBuffer> generator;
|
||||
|
||||
private GeneratingContentProvider(IntFunction<ByteBuffer> generator)
|
||||
{
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReproducible()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ByteBuffer> iterator()
|
||||
{
|
||||
return new Iterator<ByteBuffer>()
|
||||
{
|
||||
private int index;
|
||||
public ByteBuffer current;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
public boolean hasNext()
|
||||
{
|
||||
if (current == null)
|
||||
{
|
||||
current = generator.apply(index++);
|
||||
if (current == null)
|
||||
current = DONE;
|
||||
}
|
||||
return current != DONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer next()
|
||||
{
|
||||
ByteBuffer result = current;
|
||||
current = null;
|
||||
if (result == null)
|
||||
throw new NoSuchElementException();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public class HttpClientFailureTest
|
|||
startServer(new EmptyServerHandler());
|
||||
|
||||
final AtomicReference<HttpConnectionOverHTTP> connectionRef = new AtomicReference<>();
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP()
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(1)
|
||||
{
|
||||
@Override
|
||||
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
||||
|
@ -83,15 +83,14 @@ public class HttpClientFailureTest
|
|||
connectionRef.set(connection);
|
||||
return connection;
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
client.start();
|
||||
|
||||
assertThrows(ExecutionException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.onRequestHeaders(request -> connectionRef.get().getEndPoint().close())
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
});
|
||||
assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.onRequestHeaders(request -> connectionRef.get().getEndPoint().close())
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send());
|
||||
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)connectionRef.get().getHttpDestination().getConnectionPool();
|
||||
assertEquals(0, connectionPool.getConnectionCount());
|
||||
|
@ -105,7 +104,7 @@ public class HttpClientFailureTest
|
|||
startServer(new EmptyServerHandler());
|
||||
|
||||
final AtomicReference<HttpConnectionOverHTTP> connectionRef = new AtomicReference<>();
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP()
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(1)
|
||||
{
|
||||
@Override
|
||||
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
||||
|
@ -114,7 +113,7 @@ public class HttpClientFailureTest
|
|||
connectionRef.set(connection);
|
||||
return connection;
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
client.start();
|
||||
|
||||
final CountDownLatch commitLatch = new CountDownLatch(1);
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
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 java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -34,7 +26,9 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -48,13 +42,20 @@ import org.eclipse.jetty.http.HttpHeader;
|
|||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
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;
|
||||
|
||||
public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
||||
{
|
||||
@ParameterizedTest
|
||||
|
@ -128,14 +129,13 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new RedirectHandler());
|
||||
|
||||
ExecutionException x = assertThrows(ExecutionException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.method(HttpMethod.DELETE)
|
||||
.path("/301/localhost/done")
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
});
|
||||
ExecutionException x = assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.method(HttpMethod.DELETE)
|
||||
.path("/301/localhost/done")
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send());
|
||||
HttpResponseException xx = (HttpResponseException)x.getCause();
|
||||
Response response = xx.getResponse();
|
||||
assertNotNull(response);
|
||||
|
@ -170,13 +170,12 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new RedirectHandler());
|
||||
client.setMaxRedirects(1);
|
||||
|
||||
ExecutionException x = assertThrows(ExecutionException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.path("/303/localhost/302/localhost/done")
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
});
|
||||
ExecutionException x = assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.path("/303/localhost/302/localhost/done")
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send());
|
||||
HttpResponseException xx = (HttpResponseException)x.getCause();
|
||||
Response response = xx.getResponse();
|
||||
assertNotNull(response);
|
||||
|
@ -269,12 +268,11 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void testRedirectWithWrongScheme(Scenario scenario) throws Exception
|
||||
{
|
||||
start(scenario, new AbstractHandler()
|
||||
start(scenario, new EmptyServerHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setStatus(303);
|
||||
response.setHeader("Location", "ssh://localhost:" + connector.getLocalPort() + "/path");
|
||||
}
|
||||
|
@ -439,12 +437,11 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
public void testRedirectWithCorruptedBody(Scenario scenario) throws Exception
|
||||
{
|
||||
byte[] bytes = "ok".getBytes(StandardCharsets.UTF_8);
|
||||
start(scenario, new AbstractHandler()
|
||||
start(scenario, new EmptyServerHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
if (target.startsWith("/redirect"))
|
||||
{
|
||||
response.setStatus(HttpStatus.SEE_OTHER_303);
|
||||
|
@ -471,6 +468,60 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
assertArrayEquals(bytes, response.getContent());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void testRedirectToSameURL(Scenario scenario) throws Exception
|
||||
{
|
||||
start(scenario, new EmptyServerHandler()
|
||||
{
|
||||
@Override
|
||||
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
response.setStatus(HttpStatus.SEE_OTHER_303);
|
||||
response.setHeader(HttpHeader.LOCATION.asString(), request.getRequestURI());
|
||||
}
|
||||
});
|
||||
|
||||
ExecutionException x = assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.send());
|
||||
assertThat(x.getCause(), Matchers.instanceOf(HttpResponseException.class));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void testInfiniteRedirectLoopMustTimeout(Scenario scenario) throws Exception
|
||||
{
|
||||
AtomicLong counter = new AtomicLong();
|
||||
start(scenario, new EmptyServerHandler()
|
||||
{
|
||||
@Override
|
||||
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(200);
|
||||
response.setStatus(HttpStatus.SEE_OTHER_303);
|
||||
response.setHeader(HttpHeader.LOCATION.asString(), "/" + counter.getAndIncrement());
|
||||
}
|
||||
catch (InterruptedException x)
|
||||
{
|
||||
throw new RuntimeException(x);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assertThrows(TimeoutException.class, () ->
|
||||
{
|
||||
client.setMaxRedirects(-1);
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scenario.getScheme())
|
||||
.timeout(1, TimeUnit.SECONDS)
|
||||
.send();
|
||||
});
|
||||
}
|
||||
|
||||
private void testSameMethodRedirect(final Scenario scenario, final HttpMethod method, int redirectCode) throws Exception
|
||||
{
|
||||
testMethodRedirect(scenario, method, method, redirectCode);
|
||||
|
@ -519,10 +570,10 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
assertEquals(200, response.getStatus());
|
||||
}
|
||||
|
||||
private class RedirectHandler extends AbstractHandler
|
||||
private class RedirectHandler extends EmptyServerHandler
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
protected void service(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -551,10 +602,6 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
|||
// Echo content back
|
||||
IO.copy(request.getInputStream(), response.getOutputStream());
|
||||
}
|
||||
finally
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@ import javax.net.ssl.SSLPeerUnverifiedException;
|
|||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
|
@ -66,7 +68,7 @@ public class HttpClientTLSTest
|
|||
private ServerConnector connector;
|
||||
private HttpClient client;
|
||||
|
||||
private void startServer(SslContextFactory sslContextFactory, Handler handler) throws Exception
|
||||
private void startServer(SslContextFactory.Server sslContextFactory, Handler handler) throws Exception
|
||||
{
|
||||
ExecutorThreadPool serverThreads = new ExecutorThreadPool();
|
||||
serverThreads.setName("server");
|
||||
|
@ -79,22 +81,37 @@ public class HttpClientTLSTest
|
|||
server.start();
|
||||
}
|
||||
|
||||
private void startClient(SslContextFactory sslContextFactory) throws Exception
|
||||
private void startClient(SslContextFactory.Client sslContextFactory) throws Exception
|
||||
{
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
client = new HttpClient(sslContextFactory);
|
||||
client.setExecutor(clientThreads);
|
||||
clientConnector.setExecutor(clientThreads);
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
client.start();
|
||||
}
|
||||
|
||||
private SslContextFactory createSslContextFactory()
|
||||
private SslContextFactory.Server createServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private SslContextFactory.Client createClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private void configureSslContextFactory(SslContextFactory sslContextFactory)
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
@ -109,7 +126,7 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testNoCommonTLSProtocol() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
serverTLSFactory.setIncludeProtocols("TLSv1.3");
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
|
@ -123,7 +140,7 @@ public class HttpClientTLSTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
clientTLSFactory.setIncludeProtocols("TLSv1.2");
|
||||
startClient(clientTLSFactory);
|
||||
|
||||
|
@ -150,7 +167,7 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testNoCommonTLSCiphers() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
serverTLSFactory.setIncludeCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA");
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
|
@ -164,7 +181,7 @@ public class HttpClientTLSTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
clientTLSFactory.setExcludeCipherSuites(".*_SHA$");
|
||||
startClient(clientTLSFactory);
|
||||
|
||||
|
@ -191,7 +208,7 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testMismatchBetweenTLSProtocolAndTLSCiphersOnServer() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
// TLS 1.1 protocol, but only TLS 1.2 ciphers.
|
||||
serverTLSFactory.setIncludeProtocols("TLSv1.1");
|
||||
serverTLSFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
|
||||
|
@ -207,7 +224,7 @@ public class HttpClientTLSTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
startClient(clientTLSFactory);
|
||||
|
||||
CountDownLatch clientLatch = new CountDownLatch(1);
|
||||
|
@ -236,7 +253,7 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testMismatchBetweenTLSProtocolAndTLSCiphersOnClient() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
CountDownLatch serverLatch = new CountDownLatch(1);
|
||||
|
@ -249,7 +266,7 @@ public class HttpClientTLSTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
// TLS 1.1 protocol, but only TLS 1.2 ciphers.
|
||||
clientTLSFactory.setIncludeProtocols("TLSv1.1");
|
||||
clientTLSFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
|
||||
|
@ -278,7 +295,7 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testHandshakeSucceeded() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
CountDownLatch serverLatch = new CountDownLatch(1);
|
||||
|
@ -291,7 +308,7 @@ public class HttpClientTLSTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
startClient(clientTLSFactory);
|
||||
|
||||
CountDownLatch clientLatch = new CountDownLatch(1);
|
||||
|
@ -317,7 +334,7 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testHandshakeSucceededWithSessionResumption() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
AtomicReference<byte[]> serverSession = new AtomicReference<>();
|
||||
|
@ -330,7 +347,7 @@ public class HttpClientTLSTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
startClient(clientTLSFactory);
|
||||
|
||||
AtomicReference<byte[]> clientSession = new AtomicReference<>();
|
||||
|
@ -397,10 +414,10 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testClientRawCloseDoesNotInvalidateSession() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory clientTLSFactory = createClientSslContextFactory();
|
||||
clientTLSFactory.start();
|
||||
|
||||
String host = "localhost";
|
||||
|
@ -452,13 +469,17 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testServerRawCloseDetectedByClient() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory serverTLSFactory = createServerSslContextFactory();
|
||||
serverTLSFactory.start();
|
||||
try (ServerSocket server = new ServerSocket(0))
|
||||
{
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
client = new HttpClient(createSslContextFactory())
|
||||
clientConnector.setExecutor(clientThreads);
|
||||
clientConnector.setSslContextFactory(createClientSslContextFactory());
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector))
|
||||
{
|
||||
@Override
|
||||
protected ClientConnectionFactory newSslClientConnectionFactory(ClientConnectionFactory connectionFactory)
|
||||
|
@ -468,7 +489,6 @@ public class HttpClientTLSTest
|
|||
return ssl;
|
||||
}
|
||||
};
|
||||
client.setExecutor(clientThreads);
|
||||
client.start();
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
|
@ -522,10 +542,10 @@ public class HttpClientTLSTest
|
|||
@Test
|
||||
public void testHostNameVerificationFailure() throws Exception
|
||||
{
|
||||
SslContextFactory serverTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
|
||||
startServer(serverTLSFactory, new EmptyServerHandler());
|
||||
|
||||
SslContextFactory clientTLSFactory = createSslContextFactory();
|
||||
SslContextFactory.Client clientTLSFactory = createClientSslContextFactory();
|
||||
// Make sure the host name is not verified at the TLS level.
|
||||
clientTLSFactory.setEndpointIdentificationAlgorithm(null);
|
||||
// Add host name verification after the TLS handshake.
|
||||
|
|
|
@ -78,6 +78,7 @@ import org.eclipse.jetty.http.HttpMethod;
|
|||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
|
@ -90,6 +91,7 @@ import org.eclipse.jetty.util.SocketAddressResolver;
|
|||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
@ -110,7 +112,6 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
public WorkDir testdir;
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
public void testStoppingClosesConnections(Scenario scenario) throws Exception
|
||||
|
@ -186,7 +187,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.getOutputStream().write(data);
|
||||
baseRequest.setHandled(true);
|
||||
|
@ -211,7 +212,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
ServletOutputStream output = response.getOutputStream();
|
||||
|
@ -244,7 +245,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
ServletOutputStream output = response.getOutputStream();
|
||||
|
@ -281,7 +282,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
|
@ -314,7 +315,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
|
@ -348,7 +349,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
consume(request.getInputStream(), true);
|
||||
|
@ -380,7 +381,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
consume(request.getInputStream(), true);
|
||||
|
@ -411,7 +412,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
consume(request.getInputStream(), true);
|
||||
|
@ -492,7 +493,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
if (target.endsWith("/one"))
|
||||
baseRequest.getHttpChannel().getEndPoint().close();
|
||||
|
@ -611,7 +612,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
// Echo back
|
||||
IO.copy(request.getInputStream(), response.getOutputStream());
|
||||
|
@ -633,7 +634,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
@Override
|
||||
public Iterator<ByteBuffer> iterator()
|
||||
{
|
||||
return new Iterator<ByteBuffer>()
|
||||
return new Iterator<>()
|
||||
{
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
|
@ -705,7 +706,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -721,13 +722,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
final String host = "localhost";
|
||||
final int port = connector.getLocalPort();
|
||||
assertThrows(TimeoutException.class, ()->{
|
||||
client.newRequest(host, port)
|
||||
.scheme(scenario.getScheme())
|
||||
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send();
|
||||
});
|
||||
assertThrows(TimeoutException.class, () ->
|
||||
client.newRequest(host, port)
|
||||
.scheme(scenario.getScheme())
|
||||
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send());
|
||||
|
||||
// Make another request without specifying the idle timeout, should not fail
|
||||
ContentResponse response = client.newRequest(host, port)
|
||||
|
@ -741,6 +741,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
@Tag("ipv6")
|
||||
public void testSendToIPv6Address(Scenario scenario) throws Exception
|
||||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
@ -762,7 +763,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setHeader(headerName, "X");
|
||||
|
@ -820,7 +821,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.getOutputStream().write(new byte[length]);
|
||||
|
@ -881,14 +882,14 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
public void testConnectHostWithMultipleAddresses(Scenario scenario) throws Exception
|
||||
{
|
||||
startServer(scenario, new EmptyServerHandler());
|
||||
startClient(scenario, null, client ->
|
||||
startClient(scenario, client ->
|
||||
{
|
||||
client.setSocketAddressResolver(new SocketAddressResolver.Async(client.getExecutor(), client.getScheduler(), 5000)
|
||||
{
|
||||
@Override
|
||||
public void resolve(String host, int port, Promise<List<InetSocketAddress>> promise)
|
||||
{
|
||||
super.resolve(host, port, new Promise<List<InetSocketAddress>>()
|
||||
super.resolve(host, port, new Promise<>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(List<InetSocketAddress> result)
|
||||
|
@ -924,7 +925,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
ArrayList<String> userAgents = Collections.list(request.getHeaders("User-Agent"));
|
||||
|
@ -958,7 +959,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
ArrayList<String> userAgents = Collections.list(request.getHeaders("User-Agent"));
|
||||
|
@ -1160,7 +1161,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.getOutputStream().write(content);
|
||||
|
@ -1204,7 +1205,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
assertEquals(host, request.getServerName());
|
||||
|
@ -1226,7 +1227,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
// Send the headers at this point, then write the content
|
||||
byte[] content = "TEST".getBytes("UTF-8");
|
||||
|
@ -1254,7 +1255,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
// Send the headers at this point, then write the content
|
||||
response.flushBuffer();
|
||||
|
@ -1312,7 +1313,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
request.startAsync();
|
||||
|
@ -1343,9 +1344,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
Assumptions.assumeTrue(HttpScheme.HTTP.is(scenario.getScheme()));
|
||||
|
||||
ExecutionException e = assertThrows(ExecutionException.class, ()->{
|
||||
testContentDelimitedByEOFWithSlowRequest(scenario, HttpVersion.HTTP_1_0, 1024);
|
||||
});
|
||||
ExecutionException e = assertThrows(ExecutionException.class, () ->
|
||||
testContentDelimitedByEOFWithSlowRequest(scenario, HttpVersion.HTTP_1_0, 1024));
|
||||
|
||||
assertThat(e.getCause(), instanceOf(BadMessageException.class));
|
||||
assertThat(e.getCause().getMessage(), containsString("Unknown content"));
|
||||
|
@ -1355,9 +1355,8 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
@ArgumentsSource(NonSslScenarioProvider.class)
|
||||
public void testBigContentDelimitedByEOFWithSlowRequestHTTP10(Scenario scenario) throws Exception
|
||||
{
|
||||
ExecutionException e = assertThrows(ExecutionException.class, ()->{
|
||||
testContentDelimitedByEOFWithSlowRequest(scenario, HttpVersion.HTTP_1_0, 128 * 1024);
|
||||
});
|
||||
ExecutionException e = assertThrows(ExecutionException.class, () ->
|
||||
testContentDelimitedByEOFWithSlowRequest(scenario, HttpVersion.HTTP_1_0, 128 * 1024));
|
||||
|
||||
assertThat(e.getCause(), instanceOf(BadMessageException.class));
|
||||
assertThat(e.getCause().getMessage(), containsString("Unknown content"));
|
||||
|
@ -1391,7 +1390,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
// Send Connection: close to avoid that the server chunks the content with HTTP 1.1.
|
||||
|
@ -1427,7 +1426,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
int count = requests.incrementAndGet();
|
||||
if (count == maxRetries)
|
||||
|
@ -1456,7 +1455,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
ServletOutputStream output = response.getOutputStream();
|
||||
|
@ -1506,14 +1505,16 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
startServer(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
});
|
||||
|
||||
final AtomicBoolean open = new AtomicBoolean();
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP()
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSslContextFactory(scenario.newClientSslContextFactory());
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector)
|
||||
{
|
||||
@Override
|
||||
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
||||
|
@ -1528,7 +1529,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
};
|
||||
}
|
||||
}, scenario.newSslContextFactory());
|
||||
});
|
||||
client.start();
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
|
@ -1610,12 +1611,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
@Tag("ipv6")
|
||||
public void test_IPv6_Host(Scenario scenario) throws Exception
|
||||
{
|
||||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setContentType("text/plain");
|
||||
|
@ -1690,7 +1692,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(scenario, new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
assertThat(request.getHeader("Host"), Matchers.notNullValue());
|
||||
|
@ -1716,7 +1718,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
try (ServerSocket server = new ServerSocket(0))
|
||||
{
|
||||
int idleTimeout = 2000;
|
||||
startClient(scenario, null, httpClient ->
|
||||
startClient(scenario, httpClient ->
|
||||
{
|
||||
httpClient.setMaxConnectionsPerDestination(1);
|
||||
httpClient.setIdleTimeout(idleTimeout);
|
||||
|
|
|
@ -18,13 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
@ -52,13 +45,22 @@ import org.eclipse.jetty.http.HttpStatus;
|
|||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class HttpClientURITest extends AbstractHttpClientServerTest
|
||||
{
|
||||
@ParameterizedTest
|
||||
@ArgumentsSource(ScenarioProvider.class)
|
||||
@Tag("ipv6")
|
||||
public void testIPv6Host(Scenario scenario) throws Exception
|
||||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -65,7 +64,7 @@ public class HttpClientUploadDuringServerShutdown
|
|||
server.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
byte[] buffer = new byte[1024];
|
||||
|
@ -103,7 +102,7 @@ public class HttpClientUploadDuringServerShutdown
|
|||
{
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP(2), null);
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP(2));
|
||||
client.setMaxConnectionsPerDestination(2);
|
||||
client.setIdleTimeout(10000);
|
||||
client.setExecutor(clientThreads);
|
||||
|
@ -142,7 +141,7 @@ public class HttpClientUploadDuringServerShutdown
|
|||
server.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
endPointRef.set(baseRequest.getHttpChannel().getEndPoint());
|
||||
|
@ -210,7 +209,7 @@ public class HttpClientUploadDuringServerShutdown
|
|||
}
|
||||
};
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
client.setIdleTimeout(10000);
|
||||
client.setExecutor(clientThreads);
|
||||
client.start();
|
||||
|
|
|
@ -53,9 +53,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
public class HttpConnectionLifecycleTest extends AbstractHttpClientServerTest
|
||||
{
|
||||
@Override
|
||||
public HttpClient newHttpClient(Scenario scenario, HttpClientTransport transport)
|
||||
public HttpClient newHttpClient(HttpClientTransport transport)
|
||||
{
|
||||
HttpClient client = super.newHttpClient(scenario, transport);
|
||||
HttpClient client = super.newHttpClient(transport);
|
||||
client.setStrictEventOrdering(false);
|
||||
return client;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class InsufficientThreadsDetectionTest
|
|||
public void testInsufficientThreads()
|
||||
{
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool(1);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(1), null);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(1));
|
||||
httpClient.setExecutor(clientThreads);
|
||||
assertThrows(IllegalStateException.class, httpClient::start);
|
||||
}
|
||||
|
@ -39,14 +39,14 @@ public class InsufficientThreadsDetectionTest
|
|||
public void testInsufficientThreadsForMultipleHttpClients() throws Exception
|
||||
{
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool(3);
|
||||
HttpClient httpClient1 = new HttpClient(new HttpClientTransportOverHTTP(1), null);
|
||||
HttpClient httpClient1 = new HttpClient(new HttpClientTransportOverHTTP(1));
|
||||
httpClient1.setExecutor(clientThreads);
|
||||
httpClient1.start();
|
||||
|
||||
assertThrows(IllegalStateException.class, () ->
|
||||
{
|
||||
// Share the same thread pool with another instance.
|
||||
HttpClient httpClient2 = new HttpClient(new HttpClientTransportOverHTTP(1), null);
|
||||
HttpClient httpClient2 = new HttpClient(new HttpClientTransportOverHTTP(1));
|
||||
httpClient2.setExecutor(clientThreads);
|
||||
httpClient2.start();
|
||||
});
|
||||
|
|
|
@ -93,7 +93,7 @@ public class LivelockTest
|
|||
|
||||
int count = 5;
|
||||
HttpClientTransport transport = new HttpClientTransportOverHTTP(1);
|
||||
client = new HttpClient(transport, null);
|
||||
client = new HttpClient(transport);
|
||||
client.setMaxConnectionsPerDestination(2 * count);
|
||||
client.setMaxRequestsQueuedPerDestination(2 * count);
|
||||
client.setSocketAddressResolver(new SocketAddressResolver.Sync());
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ProxyConfigurationTest
|
||||
{
|
||||
@Test
|
||||
|
@ -68,6 +68,7 @@ public class ProxyConfigurationTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@Tag("ipv6")
|
||||
public void testProxyMatchesWithIncludesAndExcludesIPv6() throws Exception
|
||||
{
|
||||
HttpProxy proxy = new HttpProxy("host", 0);
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ServerConnectionCloseTest
|
|||
{
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(1), null);
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(1));
|
||||
client.setExecutor(clientThreads);
|
||||
client.start();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.client.api.Request;
|
|||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
@ -47,15 +48,20 @@ public class TLSServerConnectionCloseTest
|
|||
|
||||
private void startClient() throws Exception
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(1), sslContextFactory);
|
||||
client.setExecutor(clientThreads);
|
||||
clientConnector.setExecutor(clientThreads);
|
||||
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
client.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -42,13 +42,13 @@ import org.junit.jupiter.params.provider.ArgumentsSource;
|
|||
public class ValidatingConnectionPoolTest extends AbstractHttpClientServerTest
|
||||
{
|
||||
@Override
|
||||
public HttpClient newHttpClient(Scenario scenario, HttpClientTransport transport)
|
||||
public HttpClient newHttpClient(HttpClientTransport transport)
|
||||
{
|
||||
long timeout = 1000;
|
||||
transport.setConnectionPoolFactory(destination ->
|
||||
new ValidatingConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, destination.getHttpClient().getScheduler(), timeout));
|
||||
|
||||
return super.newHttpClient(scenario, transport);
|
||||
return super.newHttpClient(transport);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
|
|
@ -186,7 +186,7 @@ public class HttpDestinationOverHTTPTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
startServer(scenario, new EmptyServerHandler());
|
||||
long idleTimeout = 1000;
|
||||
startClient(scenario, null, httpClient -> httpClient.setIdleTimeout(idleTimeout));
|
||||
startClient(scenario, httpClient -> httpClient.setIdleTimeout(idleTimeout));
|
||||
|
||||
try(HttpDestination destination = new DuplexHttpDestination(client, new Origin("http", "localhost", connector.getLocalPort())))
|
||||
{
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client.ssl;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -34,7 +29,9 @@ import javax.net.ssl.SSLSession;
|
|||
import org.eclipse.jetty.client.EmptyServerHandler;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
@ -43,9 +40,13 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* In order to work, client authentication needs a certificate
|
||||
* signed by a CA that also signed the server certificate.
|
||||
|
@ -59,7 +60,7 @@ public class NeedWantClientAuthTest
|
|||
private ServerConnector connector;
|
||||
private HttpClient client;
|
||||
|
||||
private void startServer(SslContextFactory sslContextFactory, Handler handler) throws Exception
|
||||
private void startServer(SslContextFactory.Server sslContextFactory, Handler handler) throws Exception
|
||||
{
|
||||
QueuedThreadPool serverThreads = new QueuedThreadPool();
|
||||
serverThreads.setName("server");
|
||||
|
@ -72,19 +73,21 @@ public class NeedWantClientAuthTest
|
|||
server.start();
|
||||
}
|
||||
|
||||
private void startClient(SslContextFactory sslContextFactory) throws Exception
|
||||
private void startClient(SslContextFactory.Client sslContextFactory) throws Exception
|
||||
{
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
client = new HttpClient(sslContextFactory);
|
||||
client.setExecutor(clientThreads);
|
||||
clientConnector.setExecutor(clientThreads);
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
client.start();
|
||||
}
|
||||
|
||||
private SslContextFactory createSslContextFactory()
|
||||
private SslContextFactory.Server createServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
return sslContextFactory;
|
||||
|
@ -102,11 +105,11 @@ public class NeedWantClientAuthTest
|
|||
@Test
|
||||
public void testWantClientAuthWithoutAuth() throws Exception
|
||||
{
|
||||
SslContextFactory serverSSL = createSslContextFactory();
|
||||
SslContextFactory.Server serverSSL = createServerSslContextFactory();
|
||||
serverSSL.setWantClientAuth(true);
|
||||
startServer(serverSSL, new EmptyServerHandler());
|
||||
|
||||
SslContextFactory clientSSL = new SslContextFactory(true);
|
||||
SslContextFactory.Client clientSSL = new SslContextFactory.Client(true);
|
||||
startClient(clientSSL);
|
||||
|
||||
ContentResponse response = client.newRequest("https://localhost:" + connector.getLocalPort())
|
||||
|
@ -119,7 +122,7 @@ public class NeedWantClientAuthTest
|
|||
@Test
|
||||
public void testWantClientAuthWithAuth() throws Exception
|
||||
{
|
||||
SslContextFactory serverSSL = createSslContextFactory();
|
||||
SslContextFactory.Server serverSSL = createServerSslContextFactory();
|
||||
serverSSL.setWantClientAuth(true);
|
||||
startServer(serverSSL, new EmptyServerHandler());
|
||||
CountDownLatch handshakeLatch = new CountDownLatch(1);
|
||||
|
@ -143,7 +146,7 @@ public class NeedWantClientAuthTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientSSL = new SslContextFactory(true);
|
||||
SslContextFactory.Client clientSSL = new SslContextFactory.Client(true);
|
||||
clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks");
|
||||
clientSSL.setKeyStorePassword("storepwd");
|
||||
startClient(clientSSL);
|
||||
|
@ -166,11 +169,11 @@ public class NeedWantClientAuthTest
|
|||
// The server still sends bad_certificate to the client, but the client handshake has already
|
||||
// completed successfully its TLS handshake.
|
||||
|
||||
SslContextFactory serverSSL = createSslContextFactory();
|
||||
SslContextFactory.Server serverSSL = createServerSslContextFactory();
|
||||
serverSSL.setNeedClientAuth(true);
|
||||
startServer(serverSSL, new EmptyServerHandler());
|
||||
|
||||
SslContextFactory clientSSL = new SslContextFactory(true);
|
||||
SslContextFactory.Client clientSSL = new SslContextFactory.Client(true);
|
||||
startClient(clientSSL);
|
||||
CountDownLatch handshakeLatch = new CountDownLatch(1);
|
||||
client.addBean(new SslHandshakeListener()
|
||||
|
@ -210,7 +213,7 @@ public class NeedWantClientAuthTest
|
|||
@Test
|
||||
public void testNeedClientAuthWithAuth() throws Exception
|
||||
{
|
||||
SslContextFactory serverSSL = createSslContextFactory();
|
||||
SslContextFactory.Server serverSSL = createServerSslContextFactory();
|
||||
serverSSL.setNeedClientAuth(true);
|
||||
startServer(serverSSL, new EmptyServerHandler());
|
||||
CountDownLatch handshakeLatch = new CountDownLatch(1);
|
||||
|
@ -234,7 +237,7 @@ public class NeedWantClientAuthTest
|
|||
}
|
||||
});
|
||||
|
||||
SslContextFactory clientSSL = new SslContextFactory(true);
|
||||
SslContextFactory.Client clientSSL = new SslContextFactory.Client(true);
|
||||
clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks");
|
||||
clientSSL.setKeyStorePassword("storepwd");
|
||||
startClient(clientSSL);
|
||||
|
|
|
@ -38,9 +38,11 @@ import javax.net.ssl.SSLSocket;
|
|||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
@ -61,7 +63,7 @@ public class SslBytesClientTest extends SslBytesTest
|
|||
{
|
||||
private ExecutorService threadPool;
|
||||
private HttpClient client;
|
||||
private SslContextFactory sslContextFactory;
|
||||
private SslContextFactory.Client sslContextFactory;
|
||||
private SSLServerSocket acceptor;
|
||||
private SimpleProxy proxy;
|
||||
|
||||
|
@ -70,8 +72,11 @@ public class SslBytesClientTest extends SslBytesTest
|
|||
{
|
||||
threadPool = Executors.newCachedThreadPool();
|
||||
|
||||
sslContextFactory = new SslContextFactory(true);
|
||||
client = new HttpClient(sslContextFactory);
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
sslContextFactory = new SslContextFactory.Client(true);
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
client.setMaxConnectionsPerDestination(1);
|
||||
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
|
||||
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
|
||||
|
@ -243,7 +248,7 @@ public class SslBytesClientTest extends SslBytesTest
|
|||
|
||||
// Trigger a read to have the server write the final renegotiation steps
|
||||
server.setSoTimeout(100);
|
||||
assertThrows(SocketTimeoutException.class, ()->serverInput.read());
|
||||
assertThrows(SocketTimeoutException.class, () -> serverInput.read());
|
||||
|
||||
// Renegotiation Handshake
|
||||
record = proxy.readFromServer();
|
||||
|
|
|
@ -100,7 +100,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
private final int idleTimeout = 2000;
|
||||
private ExecutorService threadPool;
|
||||
private Server server;
|
||||
private SslContextFactory sslContextFactory;
|
||||
private SslContextFactory.Server sslContextFactory;
|
||||
private int serverPort;
|
||||
private SSLContext sslContext;
|
||||
private SimpleProxy proxy;
|
||||
|
@ -119,7 +119,7 @@ public class SslBytesServerTest extends SslBytesTest
|
|||
serverEndPoint.set(null);
|
||||
|
||||
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
|
||||
sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client.ssl;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
@ -36,16 +34,17 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class SslConnectionTest
|
||||
{
|
||||
@Test
|
||||
public void testSslConnectionClosedBeforeFill() throws Exception
|
||||
{
|
||||
File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keyStore.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.start();
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.jetty.deploy.App;
|
|||
import org.eclipse.jetty.deploy.AppLifeCycle;
|
||||
import org.eclipse.jetty.deploy.graph.Node;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
public class StandardDeployer implements AppLifeCycle.Binding
|
||||
{
|
||||
|
@ -37,9 +38,10 @@ public class StandardDeployer implements AppLifeCycle.Binding
|
|||
{
|
||||
ContextHandler handler = app.getContextHandler();
|
||||
if (handler == null)
|
||||
{
|
||||
throw new NullPointerException("No Handler created for App: " + app);
|
||||
}
|
||||
app.getDeploymentManager().getContexts().addHandler(handler);
|
||||
|
||||
Callback.Completable blocker = new Callback.Completable();
|
||||
app.getDeploymentManager().getContexts().deployHandler(handler, blocker);
|
||||
blocker.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,17 +21,12 @@ package org.eclipse.jetty.deploy.bindings;
|
|||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.AppLifeCycle;
|
||||
import org.eclipse.jetty.deploy.graph.Node;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
public class StandardUndeployer implements AppLifeCycle.Binding
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(StandardUndeployer.class);
|
||||
|
||||
@Override
|
||||
public String[] getBindingTargets()
|
||||
{
|
||||
|
@ -42,33 +37,11 @@ public class StandardUndeployer implements AppLifeCycle.Binding
|
|||
@Override
|
||||
public void processBinding(Node node, App app) throws Exception
|
||||
{
|
||||
ContextHandler handler = app.getContextHandler();
|
||||
ContextHandlerCollection chcoll = app.getDeploymentManager().getContexts();
|
||||
|
||||
recursiveRemoveContext(chcoll,handler);
|
||||
}
|
||||
|
||||
private void recursiveRemoveContext(HandlerCollection coll, ContextHandler context)
|
||||
{
|
||||
Handler children[] = coll.getHandlers();
|
||||
int originalCount = children.length;
|
||||
|
||||
for (int i = 0, n = children.length; i < n; i++)
|
||||
{
|
||||
Handler child = children[i];
|
||||
LOG.debug("Child handler {}",child);
|
||||
if (child.equals(context))
|
||||
{
|
||||
LOG.debug("Removing handler {}",child);
|
||||
coll.removeHandler(child);
|
||||
child.destroy();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("After removal: {} (originally {})",coll.getHandlers().length,originalCount);
|
||||
}
|
||||
else if (child instanceof HandlerCollection)
|
||||
{
|
||||
recursiveRemoveContext((HandlerCollection)child,context);
|
||||
}
|
||||
}
|
||||
ContextHandlerCollection contexts = app.getDeploymentManager().getContexts();
|
||||
ContextHandler context = app.getContextHandler();
|
||||
Callback.Completable blocker = new Callback.Completable();
|
||||
contexts.undeployHandler(context, blocker);
|
||||
blocker.get();
|
||||
context.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,8 +290,8 @@ Similarly, in code:
|
|||
|
||||
[source, java, subs="{sub-order}"]
|
||||
----
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setKeyStorePath();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("/path/to/keystore");
|
||||
sslContextFactory.setKeyStorePassword("secret");
|
||||
|
||||
JMXServiceURL jmxURL = new JMXServiceURL("rmi", null, 1099, "/jndi/rmi:///jmxrmi");
|
||||
|
|
|
@ -472,7 +472,7 @@ This adds a `SecureRequestCustomizer` which adds SSL Session IDs and certificate
|
|||
==== SSL Context Configuration
|
||||
|
||||
The SSL/TLS connectors for HTTPS and HTTP/2 require a certificate to establish a secure connection.
|
||||
Jetty holds certificates in standard JVM keystores and are configured as keystore and truststores on a link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.html[`SslContextFactory`] instance that is injected into an link:{JDURL}/org/eclipse/jetty/server/SslConnectionFactory.html[`SslConnectionFactory`] instance.
|
||||
Jetty holds certificates in standard JVM keystores and are configured as keystore and truststores on a link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.Server.html[`SslContextFactory.Server`] instance that is injected into an link:{JDURL}/org/eclipse/jetty/server/SslConnectionFactory.html[`SslConnectionFactory`] instance.
|
||||
An example using the keystore distributed with Jetty (containing a self signed test certificate) is in link:{GITBROWSEURL}/jetty-server/src/main/config/etc/jetty-https.xml[`jetty-https.xml`].
|
||||
Read more about SSL keystores in link:#configuring-ssl[Configuring SSL].
|
||||
|
||||
|
|
|
@ -55,9 +55,8 @@ You can re-enable these by re-declaring the ciphers you want excluded in code:
|
|||
|
||||
[source, java, subs="{sub-order}"]
|
||||
----
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setExcludeCipherSuites(
|
||||
"^.*_(MD5|SHA|SHA1)$");
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setExcludeCipherSuites("^.*_(MD5|SHA|SHA1)$");
|
||||
----
|
||||
|
||||
If, after making these changes, you still have issues using these ciphers they are likely being blocked at the JVM level.
|
||||
|
@ -664,7 +663,7 @@ the other is `$JETTY/etc/truststore` which contains intermediary CA and root CA.
|
|||
[[configuring-sslcontextfactory]]
|
||||
==== Configuring the Jetty SslContextFactory
|
||||
|
||||
The generated SSL certificates from above are held in the key store are configured in an instance of link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.html[SslContextFactory] object.
|
||||
The generated SSL certificates from above are held in the key store are configured in an instance of link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.Server.html[SslContextFactory.Server] object.
|
||||
|
||||
The `SslContextFactory` is responsible for:
|
||||
|
||||
|
@ -679,9 +678,9 @@ The `SslContextFactory` is responsible for:
|
|||
* https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol[OCSP] Support
|
||||
* Client Authentication Support
|
||||
|
||||
For Jetty Connectors, the configured `SslContextFactory` is injected into a specific ServerConnector `SslConnectionFactory`.
|
||||
For Jetty Connectors, the configured `SslContextFactory.Server` is injected into a specific ServerConnector `SslConnectionFactory`.
|
||||
|
||||
For Jetty Clients, the various constructors support using a configured `SslContextFactory`.
|
||||
For Jetty Clients, the various constructors support using a configured `SslContextFactory.Client`.
|
||||
|
||||
While the `SslContextFactory` can operate without a keystore (this mode is most suitable for the various Jetty Clients) it is best practice to at least configure the keystore being used.
|
||||
|
||||
|
@ -729,7 +728,7 @@ Implementing Conscrypt for the link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-conscry
|
|||
...
|
||||
Security.addProvider(new OpenSSLProvider());
|
||||
...
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("path/to/keystore");
|
||||
sslContextFactory.setKeyStorePassword("CleverKeyStorePassword");
|
||||
sslContextFactory.setKeyManagerPassword("OBF:VerySecretManagerPassword");
|
||||
|
@ -790,7 +789,7 @@ To do this, first create a new `${jetty.base}/etc/tweak-ssl.xml` file (this can
|
|||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
|
||||
"http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
<!-- Tweak SsslContextFactory Includes / Excludes -->
|
||||
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
|
||||
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
|
||||
<!-- Mitigate SLOTH Attack -->
|
||||
<Call name="addExcludeCipherSuites">
|
||||
<Arg>
|
||||
|
|
|
@ -75,13 +75,13 @@ There are several reasons for having multiple `HttpClient` instances including,
|
|||
|
||||
When you create a `HttpClient` instance using the parameterless constructor, you will only be able to perform plain HTTP requests and you will not be able to perform HTTPS requests.
|
||||
|
||||
In order to perform HTTPS requests, you should create first a link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.html[`SslContextFactory`], configure it, and pass it to the `HttpClient` constructor.
|
||||
In order to perform HTTPS requests, you should create first a link:{JDURL}/org/eclipse/jetty/util/ssl/SslContextFactory.Client.html[`SslContextFactory.Client`], configure it, and pass it to the `HttpClient` constructor.
|
||||
When created with a `SslContextFactory`, the `HttpClient` will be able to perform both HTTP and HTTPS requests to any domain.
|
||||
|
||||
[source, java, subs="{sub-order}"]
|
||||
----
|
||||
// Instantiate and configure the SslContextFactory
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
|
||||
// Instantiate HttpClient with the SslContextFactory
|
||||
HttpClient httpClient = new HttpClient(sslContextFactory);
|
||||
|
|
|
@ -116,7 +116,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
String value = config.getInitParameter("selectors");
|
||||
if (value != null)
|
||||
selectors = Integer.parseInt(value);
|
||||
return new HttpClient(new ProxyHttpClientTransportOverFCGI(selectors, scriptRoot), null);
|
||||
return new HttpClient(new ProxyHttpClientTransportOverFCGI(selectors, scriptRoot));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -76,7 +76,7 @@ public abstract class AbstractHttpClientServerTest
|
|||
connectionLeaks.incrementAndGet();
|
||||
}
|
||||
});
|
||||
client = new HttpClient(transport, null);
|
||||
client = new HttpClient(transport);
|
||||
client.setExecutor(executor);
|
||||
if (clientBufferPool == null)
|
||||
clientBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
|
||||
|
|
|
@ -40,7 +40,7 @@ public class ExternalFastCGIServerTest
|
|||
{
|
||||
// Assume a FastCGI server is listening on localhost:9000
|
||||
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverFCGI("/var/www/php-fcgi"), null);
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverFCGI("/var/www/php-fcgi"));
|
||||
client.start();
|
||||
|
||||
ContentResponse response = client.newRequest("localhost", 9000)
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.fcgi.server;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
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 java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -49,7 +41,6 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BytesContentProvider;
|
||||
import org.eclipse.jetty.client.util.DeferredContentProvider;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
|
@ -59,10 +50,18 @@ import org.eclipse.jetty.server.handler.AbstractHandler;
|
|||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class HttpClientTest extends AbstractHttpClientServerTest
|
||||
{
|
||||
@Test
|
||||
|
@ -85,7 +84,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.getOutputStream().write(data);
|
||||
baseRequest.setHandled(true);
|
||||
|
@ -113,7 +112,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
// Setting the Content-Length triggers the HTTP
|
||||
// content mode for response content parsing,
|
||||
|
@ -142,7 +141,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
ServletOutputStream output = response.getOutputStream();
|
||||
|
@ -174,7 +173,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
ServletOutputStream output = response.getOutputStream();
|
||||
|
@ -210,7 +209,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
|
@ -241,7 +240,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
|
@ -273,7 +272,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
|
@ -306,7 +305,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
|
@ -340,16 +339,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new EmptyServerHandler());
|
||||
|
||||
ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
|
||||
.onRequestContent(new Request.ContentListener()
|
||||
.onRequestContent((request, buffer) ->
|
||||
{
|
||||
@Override
|
||||
public void onContent(Request request, ByteBuffer buffer)
|
||||
{
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
buffer.get(bytes);
|
||||
if (!Arrays.equals(content, bytes))
|
||||
request.abort(new Exception());
|
||||
}
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
buffer.get(bytes);
|
||||
if (!Arrays.equals(content, bytes))
|
||||
request.abort(new Exception());
|
||||
})
|
||||
.content(new BytesContentProvider(content))
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
|
@ -366,16 +361,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
final AtomicInteger progress = new AtomicInteger();
|
||||
ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
|
||||
.onRequestContent(new Request.ContentListener()
|
||||
.onRequestContent((request, buffer) ->
|
||||
{
|
||||
@Override
|
||||
public void onContent(Request request, ByteBuffer buffer)
|
||||
{
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
assertEquals(1, bytes.length);
|
||||
buffer.get(bytes);
|
||||
assertEquals(bytes[0], progress.getAndIncrement());
|
||||
}
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
assertEquals(1, bytes.length);
|
||||
buffer.get(bytes);
|
||||
assertEquals(bytes[0], progress.getAndIncrement());
|
||||
})
|
||||
.content(new BytesContentProvider(new byte[]{0}, new byte[]{1}, new byte[]{2}, new byte[]{3}, new byte[]{4}))
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
|
@ -398,7 +389,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setHeader("Content-Encoding", "gzip");
|
||||
|
@ -425,7 +416,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -441,13 +432,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
final String host = "localhost";
|
||||
final int port = connector.getLocalPort();
|
||||
assertThrows(TimeoutException.class, ()->{
|
||||
client.newRequest(host, port)
|
||||
.scheme(scheme)
|
||||
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send();
|
||||
});
|
||||
assertThrows(TimeoutException.class, () ->
|
||||
client.newRequest(host, port)
|
||||
.scheme(scheme)
|
||||
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send());
|
||||
|
||||
// Make another request without specifying the idle timeout, should not fail
|
||||
ContentResponse response = client.newRequest(host, port)
|
||||
|
@ -466,7 +456,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws ServletException
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -482,13 +472,12 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
connector.setIdleTimeout(idleTimeout);
|
||||
|
||||
ExecutionException x = assertThrows(ExecutionException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.idleTimeout(4 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send();
|
||||
});
|
||||
ExecutionException x = assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.idleTimeout(4 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.timeout(3 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send());
|
||||
assertThat(x.getCause(), instanceOf(EOFException.class));
|
||||
|
||||
connector.setIdleTimeout(5 * idleTimeout);
|
||||
|
@ -505,6 +494,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@Tag("ipv6")
|
||||
public void testSendToIPv6Address() throws Exception
|
||||
{
|
||||
start(new EmptyServerHandler());
|
||||
|
@ -525,7 +515,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.getOutputStream().write(new byte[length]);
|
||||
|
@ -562,7 +552,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
request.startAsync();
|
||||
|
@ -573,14 +563,10 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
final CountDownLatch completeLatch = new CountDownLatch(1);
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.send(new Response.CompleteListener()
|
||||
.send(result ->
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
{
|
||||
if (result.isFailed())
|
||||
completeLatch.countDown();
|
||||
}
|
||||
if (result.isFailed())
|
||||
completeLatch.countDown();
|
||||
});
|
||||
|
||||
assertTrue(latch.await(5, TimeUnit.SECONDS));
|
||||
|
@ -597,7 +583,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
// Promise some content, then flush the headers, then fail to send the content.
|
||||
|
@ -609,12 +595,11 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
|
||||
try (StacklessLogging ignore = new StacklessLogging(org.eclipse.jetty.server.HttpChannel.class))
|
||||
{
|
||||
assertThrows(ExecutionException.class, () -> {
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.timeout(60, TimeUnit.SECONDS)
|
||||
.send();
|
||||
});
|
||||
assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.timeout(60, TimeUnit.SECONDS)
|
||||
.send());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,7 +622,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setHeader("Connection", "close");
|
||||
|
@ -667,7 +652,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
ServletOutputStream output = response.getOutputStream();
|
||||
output.write(65);
|
||||
|
@ -682,24 +667,13 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
final CountDownLatch completeLatch = new CountDownLatch(1);
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.scheme(scheme)
|
||||
.onResponseContentAsync(new Response.AsyncContentListener()
|
||||
.onResponseContentAsync((response, content, callback) ->
|
||||
{
|
||||
@Override
|
||||
public void onContent(Response response, ByteBuffer content, Callback callback)
|
||||
{
|
||||
contentCount.incrementAndGet();
|
||||
callbackRef.set(callback);
|
||||
contentLatch.get().countDown();
|
||||
}
|
||||
contentCount.incrementAndGet();
|
||||
callbackRef.set(callback);
|
||||
contentLatch.get().countDown();
|
||||
})
|
||||
.send(new Response.CompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
{
|
||||
completeLatch.countDown();
|
||||
}
|
||||
});
|
||||
.send(result -> completeLatch.countDown());
|
||||
|
||||
assertTrue(contentLatch.get().await(5, TimeUnit.SECONDS));
|
||||
Callback callback = callbackRef.get();
|
||||
|
|
|
@ -36,8 +36,7 @@ public class DrupalHTTP2FastCGIProxyServer
|
|||
{
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
|
||||
|
|
|
@ -18,20 +18,17 @@
|
|||
|
||||
package org.eclipse.jetty.fcgi.server.proxy;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
|
@ -41,6 +38,9 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class TryFilesFilterTest
|
||||
{
|
||||
private Server server;
|
||||
|
@ -55,13 +55,10 @@ public class TryFilesFilterTest
|
|||
connector = new ServerConnector(server);
|
||||
server.addConnector(connector);
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
|
||||
sslContextFactory.setTrustStorePassword("storepwd");
|
||||
sslConnector = new ServerConnector(server, sslContextFactory);
|
||||
SslContextFactory.Server serverSslContextFactory = new SslContextFactory.Server();
|
||||
serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
serverSslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslConnector = new ServerConnector(server, serverSslContextFactory);
|
||||
server.addConnector(sslConnector);
|
||||
|
||||
ServletContextHandler context = new ServletContextHandler(server, "/");
|
||||
|
@ -72,7 +69,15 @@ public class TryFilesFilterTest
|
|||
|
||||
context.addServlet(new ServletHolder(servlet), "/*");
|
||||
|
||||
client = new HttpClient(sslContextFactory);
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
SslContextFactory.Client clientSslContextFactory = new SslContextFactory.Client();
|
||||
clientSslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
clientSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
clientSslContextFactory.setKeyStorePassword("storepwd");
|
||||
clientSslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
|
||||
clientSslContextFactory.setTrustStorePassword("storepwd");
|
||||
clientConnector.setSslContextFactory(clientSslContextFactory);
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
server.addBean(client);
|
||||
|
||||
server.start();
|
||||
|
@ -91,7 +96,7 @@ public class TryFilesFilterTest
|
|||
prepare(new HttpServlet()
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
{
|
||||
assertTrue("https".equalsIgnoreCase(req.getScheme()));
|
||||
assertTrue(req.isSecure());
|
||||
|
|
|
@ -43,8 +43,7 @@ public class WordPressHTTP2FastCGIProxyServer
|
|||
{
|
||||
int tlsPort = 8443;
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
|
||||
|
|
|
@ -13,7 +13,7 @@ session-store
|
|||
sessions
|
||||
|
||||
[files]
|
||||
maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar
|
||||
maven://com.hazelcast/hazelcast/3.9.3|lib/hazelcast/hazelcast-3.9.3.jar
|
||||
|
||||
[xml]
|
||||
etc/sessions/hazelcast/default.xml
|
||||
|
@ -33,4 +33,4 @@ jetty.session.hazelcast.mapName=jetty-distributed-session-map
|
|||
jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE
|
||||
#jetty.session.hazelcast.configurationLocation=
|
||||
jetty.session.gracePeriod.seconds=3600
|
||||
jetty.session.savePeriod.seconds=0
|
||||
jetty.session.savePeriod.seconds=0
|
||||
|
|
|
@ -13,8 +13,8 @@ session-store
|
|||
sessions
|
||||
|
||||
[files]
|
||||
maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar
|
||||
maven://com.hazelcast/hazelcast-client/3.8.2|lib/hazelcast/hazelcast-client-3.8.2.jar
|
||||
maven://com.hazelcast/hazelcast/3.9.3|lib/hazelcast/hazelcast-3.9.3.jar
|
||||
maven://com.hazelcast/hazelcast-client/3.9.3|lib/hazelcast/hazelcast-client-3.9.3.jar
|
||||
|
||||
[xml]
|
||||
etc/sessions/hazelcast/remote.xml
|
||||
|
@ -35,4 +35,4 @@ jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE
|
|||
jetty.session.hazelcast.onlyClient=true
|
||||
#jetty.session.hazelcast.configurationLocation=
|
||||
jetty.session.gracePeriod.seconds=3600
|
||||
jetty.session.savePeriod.seconds=0
|
||||
jetty.session.savePeriod.seconds=0
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.jetty.util.BufferUtil;
|
|||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.eclipse.jetty.http.HttpCompliance.Violation.CASE_INSENSITIVE_METHOD;
|
||||
|
@ -1975,6 +1976,7 @@ public class HttpParserTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@Tag("ipv6")
|
||||
public void testIPv6Host() throws Exception
|
||||
{
|
||||
ByteBuffer buffer = BufferUtil.toBuffer(
|
||||
|
@ -2056,6 +2058,7 @@ public class HttpParserTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@Tag("ipv6")
|
||||
public void testIPv6HostPort() throws Exception
|
||||
{
|
||||
ByteBuffer buffer = BufferUtil.toBuffer(
|
||||
|
|
|
@ -65,7 +65,7 @@ public class AbstractTest
|
|||
|
||||
protected void prepareClient() throws Exception
|
||||
{
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP2(new HTTP2Client()), null);
|
||||
client = new HttpClient(new HttpClientTransportOverHTTP2(new HTTP2Client()));
|
||||
QueuedThreadPool clientExecutor = new QueuedThreadPool();
|
||||
clientExecutor.setName("client");
|
||||
client.setExecutor(clientExecutor);
|
||||
|
|
|
@ -18,10 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.http2.client.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -32,6 +30,7 @@ import org.eclipse.jetty.http.HttpStatus;
|
|||
import org.eclipse.jetty.http2.HTTP2Cipher;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
|
@ -68,7 +67,7 @@ public class DirectHTTP2OverTLSTest
|
|||
HttpConfiguration httpsConfig = new HttpConfiguration();
|
||||
httpsConfig.addCustomizer(new SecureRequestCustomizer());
|
||||
ConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig);
|
||||
ConnectionFactory ssl = new SslConnectionFactory(newSslContextFactory(), h2.getProtocol());
|
||||
ConnectionFactory ssl = new SslConnectionFactory(newServerSslContextFactory(), h2.getProtocol());
|
||||
connector = new ServerConnector(server, 1, 1, ssl, h2);
|
||||
server.addConnector(connector);
|
||||
server.setHandler(handler);
|
||||
|
@ -77,14 +76,14 @@ public class DirectHTTP2OverTLSTest
|
|||
|
||||
private void startClient() throws Exception
|
||||
{
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
QueuedThreadPool clientThreads = new QueuedThreadPool();
|
||||
clientThreads.setName("client");
|
||||
HttpClientTransportOverHTTP2 transport = new HttpClientTransportOverHTTP2(new HTTP2Client());
|
||||
clientConnector.setExecutor(clientThreads);
|
||||
clientConnector.setSslContextFactory(newClientSslContextFactory());
|
||||
HttpClientTransportOverHTTP2 transport = new HttpClientTransportOverHTTP2(new HTTP2Client(clientConnector));
|
||||
transport.setUseALPN(false);
|
||||
SslContextFactory sslContextFactory = newSslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
client = new HttpClient(transport, sslContextFactory);
|
||||
client.setExecutor(clientThreads);
|
||||
client = new HttpClient(transport);
|
||||
client.start();
|
||||
}
|
||||
|
||||
|
@ -97,14 +96,27 @@ public class DirectHTTP2OverTLSTest
|
|||
server.stop();
|
||||
}
|
||||
|
||||
private SslContextFactory newSslContextFactory()
|
||||
private SslContextFactory.Server newServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private SslContextFactory.Client newClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private void configureSslContextFactory(SslContextFactory sslContextFactory)
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setUseCipherSuitesOrder(true);
|
||||
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -115,7 +127,7 @@ public class DirectHTTP2OverTLSTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
}
|
||||
|
|
|
@ -18,16 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.http2.client.http;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ServerSocket;
|
||||
|
@ -48,7 +38,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -76,6 +65,7 @@ import org.eclipse.jetty.http2.generator.Generator;
|
|||
import org.eclipse.jetty.http2.parser.ServerParser;
|
||||
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -87,13 +77,22 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
||||
{
|
||||
@Test
|
||||
public void testPropertiesAreForwarded() throws Exception
|
||||
{
|
||||
HTTP2Client http2Client = new HTTP2Client();
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), null);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client));
|
||||
Executor executor = new QueuedThreadPool();
|
||||
httpClient.setExecutor(executor);
|
||||
httpClient.setConnectTimeout(13);
|
||||
|
@ -133,11 +132,10 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
assertThrows(ExecutionException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.onRequestCommit(request -> request.abort(new Exception("explicitly_aborted_by_test")))
|
||||
.send();
|
||||
});
|
||||
assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.onRequestCommit(request -> request.abort(new Exception("explicitly_aborted_by_test")))
|
||||
.send());
|
||||
assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
|
@ -172,11 +170,10 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
}
|
||||
});
|
||||
|
||||
assertThrows(ExecutionException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.onResponseContent((response, buffer) -> response.abort(new Exception("explicitly_aborted_by_test")))
|
||||
.send();
|
||||
});
|
||||
assertThrows(ExecutionException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
.onResponseContent((response, buffer) -> response.abort(new Exception("explicitly_aborted_by_test")))
|
||||
.send());
|
||||
assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
|
@ -186,7 +183,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
HttpVersion version = HttpVersion.fromString(request.getProtocol());
|
||||
|
@ -274,7 +271,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
lastStream.set(frame.getLastStreamId());
|
||||
latch.countDown();
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
QueuedThreadPool clientExecutor = new QueuedThreadPool();
|
||||
clientExecutor.setName("client");
|
||||
client.setExecutor(clientExecutor);
|
||||
|
@ -312,7 +309,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
assertEquals(path, request.getRequestURI());
|
||||
|
@ -336,7 +333,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
assertEquals(path, request.getRequestURI());
|
||||
|
@ -381,12 +378,11 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
client.setIdleTimeout(idleTimeout);
|
||||
client.start();
|
||||
|
||||
assertThrows(TimeoutException.class, ()->{
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
// Make sure the connection idle times out, not the stream.
|
||||
.idleTimeout(2 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send();
|
||||
});
|
||||
assertThrows(TimeoutException.class, () ->
|
||||
client.newRequest("localhost", connector.getLocalPort())
|
||||
// Make sure the connection idle times out, not the stream.
|
||||
.idleTimeout(2 * idleTimeout, TimeUnit.MILLISECONDS)
|
||||
.send());
|
||||
|
||||
assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
|
||||
}
|
||||
|
@ -436,7 +432,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
sessions.add(session);
|
||||
return super.newHttpConnection(destination, session);
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
QueuedThreadPool clientExecutor = new QueuedThreadPool();
|
||||
clientExecutor.setName("client");
|
||||
client.setExecutor(clientExecutor);
|
||||
|
@ -600,12 +596,13 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
|
|||
@Test
|
||||
public void testExternalServer() throws Exception
|
||||
{
|
||||
HTTP2Client http2Client = new HTTP2Client();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory);
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
HTTP2Client http2Client = new HTTP2Client(clientConnector);
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client));
|
||||
Executor executor = new QueuedThreadPool();
|
||||
httpClient.setExecutor(executor);
|
||||
|
||||
clientConnector.setExecutor(executor);
|
||||
httpClient.start();
|
||||
|
||||
// ContentResponse response = httpClient.GET("https://http2.akamai.com/");
|
||||
|
|
|
@ -206,7 +206,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
|
|||
}
|
||||
}, promise, context);
|
||||
}
|
||||
}, null);
|
||||
});
|
||||
QueuedThreadPool clientExecutor = new QueuedThreadPool();
|
||||
clientExecutor.setName("client");
|
||||
client.setExecutor(clientExecutor);
|
||||
|
|
|
@ -50,7 +50,7 @@ public class ClientConnector extends ContainerLifeCycle
|
|||
private Executor executor;
|
||||
private Scheduler scheduler;
|
||||
private ByteBufferPool byteBufferPool;
|
||||
private SslContextFactory sslContextFactory;
|
||||
private SslContextFactory.Client sslContextFactory;
|
||||
private SelectorManager selectorManager;
|
||||
private int selectors = 1;
|
||||
private boolean connectBlocking;
|
||||
|
@ -97,12 +97,12 @@ public class ClientConnector extends ContainerLifeCycle
|
|||
this.byteBufferPool = byteBufferPool;
|
||||
}
|
||||
|
||||
public SslContextFactory getSslContextFactory()
|
||||
public SslContextFactory.Client getSslContextFactory()
|
||||
{
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
public void setSslContextFactory(SslContextFactory sslContextFactory)
|
||||
public void setSslContextFactory(SslContextFactory.Client sslContextFactory)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException();
|
||||
|
@ -192,9 +192,9 @@ public class ClientConnector extends ContainerLifeCycle
|
|||
removeBean(selectorManager);
|
||||
}
|
||||
|
||||
protected SslContextFactory newSslContextFactory()
|
||||
protected SslContextFactory.Client newSslContextFactory()
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory(false);
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(false);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
|
|
@ -295,8 +295,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
LOG.ignore(x);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -309,8 +308,7 @@ public class ManagedSelector extends ContainerLifeCycle implements Dumpable
|
|||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
LOG.ignore(x);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,9 +389,9 @@ abstract public class WriteFlusher
|
|||
boolean progress = true;
|
||||
while (progress && buffers != null)
|
||||
{
|
||||
long before = remaining(buffers);
|
||||
long before = BufferUtil.remaining(buffers);
|
||||
boolean flushed = _endPoint.flush(buffers);
|
||||
long after = remaining(buffers);
|
||||
long after = BufferUtil.remaining(buffers);
|
||||
long written = before - after;
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -441,16 +441,6 @@ abstract public class WriteFlusher
|
|||
return buffers == null ? EMPTY_BUFFERS : buffers;
|
||||
}
|
||||
|
||||
private long remaining(ByteBuffer[] buffers)
|
||||
{
|
||||
if (buffers == null)
|
||||
return 0;
|
||||
long result = 0;
|
||||
for (ByteBuffer buffer : buffers)
|
||||
result += buffer.remaining();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the flusher of a failure
|
||||
*
|
||||
|
|
|
@ -835,6 +835,12 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
LOG.debug("flush b[{}]={}", i++, BufferUtil.toDetailString(b));
|
||||
}
|
||||
|
||||
// finish of any previous flushes
|
||||
if (BufferUtil.hasContent(_encryptedOutput) && !getEndPoint().flush(_encryptedOutput))
|
||||
return false;
|
||||
|
||||
boolean isEmpty = BufferUtil.isEmpty(appOuts);
|
||||
|
||||
Boolean result = null;
|
||||
try
|
||||
{
|
||||
|
@ -866,7 +872,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
if (filled < 0)
|
||||
throw new IOException("Broken pipe");
|
||||
}
|
||||
return result = false;
|
||||
return result = isEmpty;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected HandshakeStatus " + status);
|
||||
|
@ -895,10 +901,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
_sslEngine.isOutboundDone());
|
||||
|
||||
// Was all the data consumed?
|
||||
boolean allConsumed = true;
|
||||
for (ByteBuffer b : appOuts)
|
||||
if (BufferUtil.hasContent(b))
|
||||
allConsumed = false;
|
||||
isEmpty = BufferUtil.isEmpty(appOuts);
|
||||
|
||||
// if we have net bytes, let's try to flush them
|
||||
boolean flushed = true;
|
||||
|
@ -906,7 +909,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
flushed = getEndPoint().flush(_encryptedOutput);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("net flushed={}, ac={}", flushed, allConsumed);
|
||||
LOG.debug("net flushed={}, ac={}", flushed, isEmpty);
|
||||
|
||||
// Now deal with the results returned from the wrap
|
||||
Status wrap = wrapResult.getStatus();
|
||||
|
@ -919,7 +922,7 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
if (!flushed)
|
||||
return result = false;
|
||||
getEndPoint().shutdownOutput();
|
||||
if (allConsumed)
|
||||
if (isEmpty)
|
||||
return result = true;
|
||||
throw new IOException("Broken pipe");
|
||||
}
|
||||
|
@ -936,15 +939,20 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
if (isRenegotiating() && !allowRenegotiate())
|
||||
{
|
||||
getEndPoint().shutdownOutput();
|
||||
if (allConsumed && BufferUtil.isEmpty(_encryptedOutput))
|
||||
if (isEmpty && BufferUtil.isEmpty(_encryptedOutput))
|
||||
return result = true;
|
||||
throw new IOException("Broken pipe");
|
||||
}
|
||||
|
||||
if (!flushed)
|
||||
return result = false;
|
||||
if (allConsumed)
|
||||
return result = true;
|
||||
|
||||
if (isEmpty)
|
||||
{
|
||||
if (wrapResult.getHandshakeStatus() != HandshakeStatus.NEED_WRAP ||
|
||||
wrapResult.bytesProduced() == 0)
|
||||
return result = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1073,14 +1081,15 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
@Override
|
||||
public void doShutdownOutput()
|
||||
{
|
||||
final EndPoint endp = getEndPoint();
|
||||
try
|
||||
{
|
||||
boolean close;
|
||||
boolean flush = false;
|
||||
synchronized (_decryptedEndPoint)
|
||||
{
|
||||
boolean ishut = getEndPoint().isInputShutdown();
|
||||
boolean oshut = getEndPoint().isOutputShutdown();
|
||||
boolean ishut = endp.isInputShutdown();
|
||||
boolean oshut = endp.isOutputShutdown();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("shutdownOutput: {} oshut={}, ishut={} {}", SslConnection.this, oshut, ishut);
|
||||
|
||||
|
@ -1097,16 +1106,28 @@ public class SslConnection extends AbstractConnection implements Connection.Upgr
|
|||
}
|
||||
|
||||
if (flush)
|
||||
flush(BufferUtil.EMPTY_BUFFER); // Send the TLS close message.
|
||||
{
|
||||
if (!flush(BufferUtil.EMPTY_BUFFER) && !close)
|
||||
{
|
||||
Thread.yield();
|
||||
// if we still can't flush, but we are not closing the endpoint,
|
||||
// let's just flush the encrypted output in the background.
|
||||
// and continue as if we are closed. The assumption here is that
|
||||
// the encrypted buffer will contain the entire close handshake
|
||||
// and that a call to flush(EMPTY_BUFFER) is not needed.
|
||||
endp.write(Callback.from(() -> {}, t -> endp.close()), _encryptedOutput);
|
||||
}
|
||||
}
|
||||
|
||||
if (close)
|
||||
getEndPoint().close();
|
||||
endp.close();
|
||||
else
|
||||
ensureFillInterested();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
LOG.ignore(x);
|
||||
getEndPoint().close();
|
||||
endp.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -625,24 +625,23 @@ public class SocketChannelEndPointTest
|
|||
public static class SslScenario implements Scenario
|
||||
{
|
||||
private final NormalScenario _normalScenario;
|
||||
private final SslContextFactory __sslCtxFactory = new SslContextFactory();
|
||||
private final ByteBufferPool __byteBufferPool = new MappedByteBufferPool();
|
||||
private final SslContextFactory _sslCtxFactory = new SslContextFactory.Server();
|
||||
private final ByteBufferPool _byteBufferPool = new MappedByteBufferPool();
|
||||
|
||||
public SslScenario(NormalScenario normalScenario) throws Exception
|
||||
{
|
||||
_normalScenario = normalScenario;
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
__sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
|
||||
__sslCtxFactory.setKeyStorePassword("storepwd");
|
||||
__sslCtxFactory.setKeyManagerPassword("keypwd");
|
||||
__sslCtxFactory.setEndpointIdentificationAlgorithm("");
|
||||
__sslCtxFactory.start();
|
||||
_sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
|
||||
_sslCtxFactory.setKeyStorePassword("storepwd");
|
||||
_sslCtxFactory.setKeyManagerPassword("keypwd");
|
||||
_sslCtxFactory.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket newClient(ServerSocketChannel connector) throws IOException
|
||||
{
|
||||
SSLSocket socket = __sslCtxFactory.newSslSocket();
|
||||
SSLSocket socket = _sslCtxFactory.newSslSocket();
|
||||
socket.connect(connector.socket().getLocalSocketAddress());
|
||||
return socket;
|
||||
}
|
||||
|
@ -650,11 +649,11 @@ public class SocketChannelEndPointTest
|
|||
@Override
|
||||
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Executor executor, AtomicInteger blockAt, AtomicInteger writeCount)
|
||||
{
|
||||
SSLEngine engine = __sslCtxFactory.newSSLEngine();
|
||||
SSLEngine engine = _sslCtxFactory.newSSLEngine();
|
||||
engine.setUseClientMode(false);
|
||||
SslConnection sslConnection = new SslConnection(__byteBufferPool, executor, endpoint, engine);
|
||||
sslConnection.setRenegotiationAllowed(__sslCtxFactory.isRenegotiationAllowed());
|
||||
sslConnection.setRenegotiationLimit(__sslCtxFactory.getRenegotiationLimit());
|
||||
SslConnection sslConnection = new SslConnection(_byteBufferPool, executor, endpoint, engine);
|
||||
sslConnection.setRenegotiationAllowed(_sslCtxFactory.isRenegotiationAllowed());
|
||||
sslConnection.setRenegotiationLimit(_sslCtxFactory.getRenegotiationLimit());
|
||||
Connection appConnection = _normalScenario.newConnection(channel, sslConnection.getDecryptedEndPoint(), executor, blockAt, writeCount);
|
||||
sslConnection.getDecryptedEndPoint().setConnection(appConnection);
|
||||
return sslConnection;
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
|
@ -31,6 +32,7 @@ import java.nio.channels.SocketChannel;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.net.ssl.SSLEngine;
|
||||
|
@ -50,6 +52,8 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
@ -60,9 +64,11 @@ public class SslConnectionTest
|
|||
private static final int TIMEOUT = 1000000;
|
||||
private static ByteBufferPool __byteBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
|
||||
|
||||
private final SslContextFactory _sslCtxFactory =new SslContextFactory();
|
||||
private final SslContextFactory _sslCtxFactory = new SslContextFactory.Server();
|
||||
protected volatile EndPoint _lastEndp;
|
||||
private volatile boolean _testFill=true;
|
||||
private volatile boolean _onXWriteThenShutdown=false;
|
||||
|
||||
private volatile FutureCallback _writeCallback;
|
||||
protected ServerSocketChannel _connector;
|
||||
final AtomicInteger _dispatches = new AtomicInteger();
|
||||
|
@ -92,7 +98,6 @@ public class SslConnectionTest
|
|||
return sslConnection;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey)
|
||||
{
|
||||
|
@ -105,6 +110,7 @@ public class SslConnectionTest
|
|||
|
||||
static final AtomicInteger __startBlocking = new AtomicInteger();
|
||||
static final AtomicInteger __blockFor = new AtomicInteger();
|
||||
static final AtomicBoolean __onIncompleteFlush = new AtomicBoolean();
|
||||
private static class TestEP extends SocketChannelEndPoint
|
||||
{
|
||||
public TestEP(SelectableChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
||||
|
@ -115,13 +121,14 @@ public class SslConnectionTest
|
|||
@Override
|
||||
protected void onIncompleteFlush()
|
||||
{
|
||||
super.onIncompleteFlush();
|
||||
__onIncompleteFlush.set(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean flush(ByteBuffer... buffers) throws IOException
|
||||
{
|
||||
__onIncompleteFlush.set(false);
|
||||
if (__startBlocking.get()==0 || __startBlocking.decrementAndGet()==0)
|
||||
{
|
||||
if (__blockFor.get()>0 && __blockFor.getAndDecrement()>0)
|
||||
|
@ -133,7 +140,6 @@ public class SslConnectionTest
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void initSSL() throws Exception
|
||||
{
|
||||
|
@ -143,7 +149,6 @@ public class SslConnectionTest
|
|||
_sslCtxFactory.setKeyManagerPassword("keypwd");
|
||||
_sslCtxFactory.setRenegotiationAllowed(true);
|
||||
_sslCtxFactory.setRenegotiationLimit(-1);
|
||||
_sslCtxFactory.setEndpointIdentificationAlgorithm(null);
|
||||
startManager();
|
||||
}
|
||||
|
||||
|
@ -227,20 +232,23 @@ public class SslConnectionTest
|
|||
filled=endp.fill(_in);
|
||||
}
|
||||
|
||||
boolean shutdown = _onXWriteThenShutdown && BufferUtil.toString(_in).contains("X");
|
||||
|
||||
// Write everything
|
||||
int l=_in.remaining();
|
||||
if (l>0)
|
||||
{
|
||||
FutureCallback blockingWrite= new FutureCallback();
|
||||
|
||||
endp.write(blockingWrite,_in);
|
||||
blockingWrite.get();
|
||||
if (shutdown)
|
||||
endp.shutdownOutput();
|
||||
}
|
||||
|
||||
// are we done?
|
||||
if (endp.isInputShutdown())
|
||||
{
|
||||
if (endp.isInputShutdown() || shutdown)
|
||||
endp.shutdownOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(InterruptedException|EofException e)
|
||||
|
@ -426,7 +434,7 @@ public class SslConnectionTest
|
|||
public void testBlockedWrite() throws Exception
|
||||
{
|
||||
startSSL();
|
||||
try (Socket client = newClient())
|
||||
try (SSLSocket client = newClient())
|
||||
{
|
||||
client.setSoTimeout(5000);
|
||||
try (SocketChannel server = _connector.accept())
|
||||
|
@ -434,21 +442,78 @@ public class SslConnectionTest
|
|||
server.configureBlocking(false);
|
||||
_manager.accept(server);
|
||||
|
||||
__startBlocking.set(5);
|
||||
__blockFor.set(3);
|
||||
|
||||
client.getOutputStream().write("Hello".getBytes(StandardCharsets.UTF_8));
|
||||
byte[] buffer = new byte[1024];
|
||||
int len = client.getInputStream().read(buffer);
|
||||
assertEquals(5, len);
|
||||
assertEquals("Hello", new String(buffer, 0, len, StandardCharsets.UTF_8));
|
||||
|
||||
__startBlocking.set(0);
|
||||
__blockFor.set(2);
|
||||
_dispatches.set(0);
|
||||
client.getOutputStream().write("World".getBytes(StandardCharsets.UTF_8));
|
||||
len = 5;
|
||||
while (len > 0)
|
||||
len -= client.getInputStream().read(buffer);
|
||||
assertEquals(0, len);
|
||||
|
||||
try
|
||||
{
|
||||
client.setSoTimeout(500);
|
||||
client.getInputStream().read(buffer);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
catch(SocketTimeoutException e)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
assertTrue(__onIncompleteFlush.get());
|
||||
((TestEP)_lastEndp).getWriteFlusher().completeWrite();
|
||||
|
||||
len = client.getInputStream().read(buffer);
|
||||
assertEquals("World", new String(buffer, 0, len, StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockedClose() throws Exception
|
||||
{
|
||||
startSSL();
|
||||
try (SSLSocket client = newClient())
|
||||
{
|
||||
client.setSoTimeout(5000);
|
||||
try (SocketChannel server = _connector.accept())
|
||||
{
|
||||
server.configureBlocking(false);
|
||||
_manager.accept(server);
|
||||
|
||||
//__startBlocking.set(5);
|
||||
//__blockFor.set(3);
|
||||
|
||||
client.getOutputStream().write("Short".getBytes(StandardCharsets.UTF_8));
|
||||
byte[] buffer = new byte[1024];
|
||||
int len = client.getInputStream().read(buffer);
|
||||
assertEquals("Short", new String(buffer, 0, len, StandardCharsets.UTF_8));
|
||||
|
||||
_onXWriteThenShutdown=true;
|
||||
__startBlocking.set(2); // block on the close handshake flush
|
||||
__blockFor.set(Integer.MAX_VALUE); // > retry loops in SslConnection + 1
|
||||
client.getOutputStream().write("This is a much longer example with X".getBytes(StandardCharsets.UTF_8));
|
||||
len = client.getInputStream().read(buffer);
|
||||
assertEquals("This is a much longer example with X", new String(buffer, 0, len, StandardCharsets.UTF_8));
|
||||
|
||||
try
|
||||
{
|
||||
client.setSoTimeout(500);
|
||||
client.getInputStream().read(buffer);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
catch(SocketTimeoutException e)
|
||||
{
|
||||
}
|
||||
|
||||
__blockFor.set(0);
|
||||
assertTrue(__onIncompleteFlush.get());
|
||||
((TestEP)_lastEndp).getWriteFlusher().completeWrite();
|
||||
len = client.getInputStream().read(buffer);
|
||||
assertThat(len, is(len));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +543,6 @@ public class SslConnectionTest
|
|||
String line = in.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
// System.err.println(line);
|
||||
count.countDown();
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +555,6 @@ public class SslConnectionTest
|
|||
for (int i = 0; i < LINES; i++)
|
||||
{
|
||||
client.getOutputStream().write(("HelloWorld " + i + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
// System.err.println("wrote");
|
||||
if (i % 1000 == 0)
|
||||
{
|
||||
client.getOutputStream().flush();
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.io;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
@ -32,12 +28,15 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class SslEngineBehaviorTest
|
||||
{
|
||||
private static SslContextFactory sslCtxFactory;
|
||||
|
@ -45,12 +44,11 @@ public class SslEngineBehaviorTest
|
|||
@BeforeAll
|
||||
public static void startSsl() throws Exception
|
||||
{
|
||||
sslCtxFactory = new SslContextFactory();
|
||||
sslCtxFactory = new SslContextFactory.Server();
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath());
|
||||
sslCtxFactory.setKeyStorePassword("storepwd");
|
||||
sslCtxFactory.setKeyManagerPassword("keypwd");
|
||||
sslCtxFactory.setEndpointIdentificationAlgorithm("");
|
||||
sslCtxFactory.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.jmx;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
|
@ -40,6 +36,10 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* Running the tests of this class in the same JVM results often in
|
||||
* <pre>
|
||||
|
@ -227,7 +227,7 @@ public class ConnectorServerTest
|
|||
@Test
|
||||
public void testJMXOverTLS() throws Exception
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory.Server();
|
||||
String keyStorePath = MavenTestingUtils.getTestResourcePath("keystore.jks").toString();
|
||||
String keyStorePassword = "storepwd";
|
||||
sslContextFactory.setKeyStorePath(keyStorePath);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.9</version>
|
||||
<version>${slf4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<!-- ============================================================= -->
|
||||
<!-- Create a TLS (SSL) Context Factory for later reuse -->
|
||||
<!-- ============================================================= -->
|
||||
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
|
||||
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
|
||||
<Set name="Provider"><SystemProperty name="jetty.sslContext.provider"/></Set>
|
||||
<Set name="KeyStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" default="etc/keystore"/></Set>
|
||||
<Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.client.HttpClient;
|
|||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.JavaVersion;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
|
@ -137,8 +138,8 @@ public class TestJettyOSGiBootHTTP2Conscrypt
|
|||
Path path = Paths.get("src", "test", "config");
|
||||
File keys = path.resolve("etc").resolve("keystore").toFile();
|
||||
|
||||
HTTP2Client http2Client = new HTTP2Client();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setTrustStorePath(keys.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
|
||||
|
@ -150,7 +151,9 @@ public class TestJettyOSGiBootHTTP2Conscrypt
|
|||
// Conscrypt enables TLSv1.3 by default but it's not supported in Java 8.
|
||||
sslContextFactory.addExcludeProtocols("TLSv1.3");
|
||||
}
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory);
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
HTTP2Client http2Client = new HTTP2Client(clientConnector);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client));
|
||||
Executor executor = new QueuedThreadPool();
|
||||
httpClient.setExecutor(executor);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.client.HttpClient;
|
|||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.Test;
|
||||
|
@ -131,15 +132,16 @@ public class TestJettyOSGiBootHTTP2JDK9
|
|||
Path path = Paths.get("src", "test", "config");
|
||||
File keys = path.resolve("etc").resolve("keystore").toFile();
|
||||
|
||||
//set up client to do http2
|
||||
http2Client = new HTTP2Client();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setTrustStorePath(keys.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
|
||||
sslContextFactory.setTrustStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory);
|
||||
clientConnector.setSslContextFactory(sslContextFactory);
|
||||
http2Client = new HTTP2Client(clientConnector);
|
||||
httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client));
|
||||
Executor executor = new QueuedThreadPool();
|
||||
httpClient.setExecutor(executor);
|
||||
httpClient.start();
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -31,7 +32,9 @@ import javax.servlet.http.HttpServletResponse;
|
|||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
@ -56,7 +59,6 @@ import static org.ops4j.pax.exam.CoreOptions.systemProperty;
|
|||
*/
|
||||
public class TestOSGiUtil
|
||||
{
|
||||
|
||||
public static final String BUNDLE_DEBUG = "bundle.debug";
|
||||
|
||||
public static List<Option> configureJettyHomeAndPort(boolean ssl,String jettySelectorFileName)
|
||||
|
@ -276,10 +278,10 @@ public class TestOSGiUtil
|
|||
return bundleContext.getAllServiceReferences(service, null);
|
||||
}
|
||||
|
||||
protected static SslContextFactory newSslContextFactory()
|
||||
protected static SslContextFactory.Client newClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory(true);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm("");
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(true);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
|
@ -330,7 +332,10 @@ public class TestOSGiUtil
|
|||
}, null, null);
|
||||
|
||||
// now test the servlet
|
||||
HttpClient client = protocol.equals("https") ? new HttpClient(newSslContextFactory()) : new HttpClient();
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
clientConnector.setSslContextFactory(newClientSslContextFactory());
|
||||
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
try
|
||||
{
|
||||
client.start();
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.proxy;
|
|||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -84,21 +83,17 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|||
public abstract class AbstractProxyServlet extends HttpServlet
|
||||
{
|
||||
protected static final String CLIENT_REQUEST_ATTRIBUTE = "org.eclipse.jetty.proxy.clientRequest";
|
||||
protected static final Set<String> HOP_HEADERS;
|
||||
static
|
||||
{
|
||||
Set<String> hopHeaders = new HashSet<>();
|
||||
hopHeaders.add("connection");
|
||||
hopHeaders.add("keep-alive");
|
||||
hopHeaders.add("proxy-authorization");
|
||||
hopHeaders.add("proxy-authenticate");
|
||||
hopHeaders.add("proxy-connection");
|
||||
hopHeaders.add("transfer-encoding");
|
||||
hopHeaders.add("te");
|
||||
hopHeaders.add("trailer");
|
||||
hopHeaders.add("upgrade");
|
||||
HOP_HEADERS = Collections.unmodifiableSet(hopHeaders);
|
||||
}
|
||||
protected static final Set<String> HOP_HEADERS = Set.of(
|
||||
"connection",
|
||||
"keep-alive",
|
||||
"proxy-authorization",
|
||||
"proxy-authenticate",
|
||||
"proxy-connection",
|
||||
"transfer-encoding",
|
||||
"te",
|
||||
"trailer",
|
||||
"upgrade"
|
||||
);
|
||||
|
||||
private final Set<String> _whiteList = new HashSet<>();
|
||||
private final Set<String> _blackList = new HashSet<>();
|
||||
|
@ -353,11 +348,11 @@ public abstract class AbstractProxyServlet extends HttpServlet
|
|||
*/
|
||||
protected HttpClient newHttpClient()
|
||||
{
|
||||
int selectors = Math.max(1,ProcessorUtils.availableProcessors()/2);
|
||||
int selectors = Math.max(1, ProcessorUtils.availableProcessors() / 2);
|
||||
String value = getServletConfig().getInitParameter("selectors");
|
||||
if (value != null)
|
||||
selectors = Integer.parseInt(value);
|
||||
return new HttpClient(new HttpClientTransportOverHTTP(selectors),null);
|
||||
return new HttpClient(new HttpClientTransportOverHTTP(selectors));
|
||||
}
|
||||
|
||||
protected HttpClient getHttpClient()
|
||||
|
|
|
@ -48,12 +48,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
|
||||
public class ConnectHandlerSSLTest extends AbstractConnectHandlerTest
|
||||
{
|
||||
private SslContextFactory sslContextFactory;
|
||||
private SslContextFactory.Server sslContextFactory;
|
||||
|
||||
@BeforeEach
|
||||
public void prepare() throws Exception
|
||||
{
|
||||
sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory = new SslContextFactory.Server();
|
||||
String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
sslContextFactory.setKeyStorePath(keyStorePath);
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.eclipse.jetty.util.B64Code;
|
|||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
@ -88,6 +89,7 @@ public class ConnectHandlerTest extends AbstractConnectHandlerTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@Tag("ipv6")
|
||||
public void testCONNECTwithIPv6() throws Exception
|
||||
{
|
||||
String hostPort = "[::1]:" + serverConnector.getLocalPort();
|
||||
|
|
|
@ -25,9 +25,11 @@ import java.util.stream.Stream;
|
|||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpProxy;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.server.AbstractConnectionFactory;
|
||||
|
@ -60,9 +62,9 @@ public class ForwardProxyServerTest
|
|||
String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
|
||||
// no server SSL
|
||||
SslContextFactory scenario1 = null;
|
||||
SslContextFactory.Server scenario1 = null;
|
||||
// basic server SSL
|
||||
SslContextFactory scenario2 = new SslContextFactory();
|
||||
SslContextFactory.Server scenario2 = new SslContextFactory.Server();
|
||||
scenario2.setKeyStorePath(keyStorePath);
|
||||
scenario2.setKeyStorePassword("storepwd");
|
||||
scenario2.setKeyManagerPassword("keypwd");
|
||||
|
@ -71,13 +73,13 @@ public class ForwardProxyServerTest
|
|||
return Stream.of(scenario1, scenario2).map(Arguments::of);
|
||||
}
|
||||
|
||||
private SslContextFactory serverSslContextFactory;
|
||||
private SslContextFactory.Server serverSslContextFactory;
|
||||
private Server server;
|
||||
private ServerConnector serverConnector;
|
||||
private Server proxy;
|
||||
private ServerConnector proxyConnector;
|
||||
|
||||
public void init(SslContextFactory scenario)
|
||||
public void init(SslContextFactory.Server scenario)
|
||||
{
|
||||
serverSslContextFactory = scenario;
|
||||
}
|
||||
|
@ -143,7 +145,7 @@ public class ForwardProxyServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testRequestTarget(SslContextFactory scenario) throws Exception
|
||||
public void testRequestTarget(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
|
||||
|
@ -202,14 +204,16 @@ public class ForwardProxyServerTest
|
|||
});
|
||||
startProxy();
|
||||
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
SslContextFactory clientSsl = new SslContextFactory();
|
||||
SslContextFactory.Client clientSsl = new SslContextFactory.Client();
|
||||
clientSsl.setKeyStorePath(keyStorePath);
|
||||
clientSsl.setKeyStorePassword("storepwd");
|
||||
clientSsl.setKeyManagerPassword("keypwd");
|
||||
clientSsl.setEndpointIdentificationAlgorithm(null);
|
||||
clientConnector.setSslContextFactory(clientSsl);
|
||||
|
||||
HttpClient httpClient = new HttpClient(clientSsl);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
httpClient.start();
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.jetty.client.Origin;
|
|||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.util.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
|
@ -48,6 +49,7 @@ import org.eclipse.jetty.http.HttpMethod;
|
|||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.HttpConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
|
@ -80,9 +82,9 @@ public class ForwardProxyTLSServerTest
|
|||
String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
|
||||
// no server SSL
|
||||
SslContextFactory scenario1 = null;
|
||||
SslContextFactory.Server scenario1 = null;
|
||||
// basic server SSL
|
||||
SslContextFactory scenario2 = new SslContextFactory();
|
||||
SslContextFactory.Server scenario2 = new SslContextFactory.Server();
|
||||
scenario2.setKeyStorePath(keyStorePath);
|
||||
scenario2.setKeyStorePassword("storepwd");
|
||||
scenario2.setKeyManagerPassword("keypwd");
|
||||
|
@ -91,13 +93,13 @@ public class ForwardProxyTLSServerTest
|
|||
return Stream.of(scenario1, scenario2).map(Arguments::of);
|
||||
}
|
||||
|
||||
private SslContextFactory proxySslContextFactory;
|
||||
private SslContextFactory.Server proxySslContextFactory;
|
||||
private Server server;
|
||||
private ServerConnector serverConnector;
|
||||
private Server proxy;
|
||||
private ServerConnector proxyConnector;
|
||||
|
||||
public void init(SslContextFactory scenario)
|
||||
public void init(SslContextFactory.Server scenario)
|
||||
{
|
||||
proxySslContextFactory = scenario;
|
||||
}
|
||||
|
@ -137,22 +139,35 @@ public class ForwardProxyTLSServerTest
|
|||
return new HttpProxy(new Origin.Address("localhost", proxyConnector.getLocalPort()), proxySslContextFactory != null);
|
||||
}
|
||||
|
||||
private static SslContextFactory newServerSslContextFactory()
|
||||
private HttpClient newHttpClient()
|
||||
{
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setSelectors(1);
|
||||
clientConnector.setSslContextFactory(newClientSslContextFactory());
|
||||
return new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
}
|
||||
|
||||
private static SslContextFactory.Server newServerSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private static SslContextFactory.Client newClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
configureSslContextFactory(sslContextFactory);
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
private static void configureSslContextFactory(SslContextFactory sslContextFactory)
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
sslContextFactory.setKeyStorePath(keyStorePath);
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
return sslContextFactory;
|
||||
|
||||
}
|
||||
|
||||
private static SslContextFactory newClientSslContextFactory()
|
||||
{
|
||||
SslContextFactory sslContextFactory = newServerSslContextFactory();
|
||||
sslContextFactory.setEndpointIdentificationAlgorithm(null);
|
||||
return sslContextFactory;
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
@ -182,13 +197,13 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testOneExchange(SslContextFactory scenario) throws Exception
|
||||
public void testOneExchange(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
startTLSServer(new ServerHandler());
|
||||
startProxy();
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
httpClient.start();
|
||||
|
||||
|
@ -218,13 +233,13 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testTwoExchanges(SslContextFactory scenario) throws Exception
|
||||
public void testTwoExchanges(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
startTLSServer(new ServerHandler());
|
||||
startProxy();
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
httpClient.start();
|
||||
|
||||
|
@ -265,20 +280,20 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testTwoConcurrentExchanges(SslContextFactory scenario) throws Exception
|
||||
public void testTwoConcurrentExchanges(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
startTLSServer(new ServerHandler());
|
||||
startProxy();
|
||||
|
||||
final HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
httpClient.start();
|
||||
|
||||
try
|
||||
{
|
||||
final AtomicReference<Connection> connection = new AtomicReference<>();
|
||||
final CountDownLatch connectionLatch = new CountDownLatch(1);
|
||||
AtomicReference<Connection> connection = new AtomicReference<>();
|
||||
CountDownLatch connectionLatch = new CountDownLatch(1);
|
||||
String content1 = "BODY";
|
||||
ContentResponse response1 = httpClient.newRequest("localhost", serverConnector.getLocalPort())
|
||||
.scheme(HttpScheme.HTTPS.asString())
|
||||
|
@ -287,7 +302,7 @@ public class ForwardProxyTLSServerTest
|
|||
.onRequestCommit(request ->
|
||||
{
|
||||
Destination destination = httpClient.getDestination(HttpScheme.HTTPS.asString(), "localhost", serverConnector.getLocalPort());
|
||||
destination.newConnection(new Promise.Adapter<Connection>()
|
||||
destination.newConnection(new Promise.Adapter<>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(Connection result)
|
||||
|
@ -332,7 +347,7 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testShortIdleTimeoutOverriddenByRequest(SslContextFactory scenario) throws Exception
|
||||
public void testShortIdleTimeoutOverriddenByRequest(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
// Short idle timeout for HttpClient.
|
||||
|
@ -357,7 +372,7 @@ public class ForwardProxyTLSServerTest
|
|||
}
|
||||
});
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
// Short idle timeout for HttpClient.
|
||||
httpClient.setIdleTimeout(idleTimeout);
|
||||
|
@ -388,7 +403,7 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testProxyDown(SslContextFactory scenario) throws Exception
|
||||
public void testProxyDown(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
startTLSServer(new ServerHandler());
|
||||
|
@ -396,7 +411,7 @@ public class ForwardProxyTLSServerTest
|
|||
int proxyPort = proxyConnector.getLocalPort();
|
||||
stopProxy();
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(new Origin.Address("localhost", proxyPort), proxySslContextFactory != null));
|
||||
httpClient.start();
|
||||
|
||||
|
@ -416,7 +431,7 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testServerDown(SslContextFactory scenario) throws Exception
|
||||
public void testServerDown(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
startTLSServer(new ServerHandler());
|
||||
|
@ -424,7 +439,7 @@ public class ForwardProxyTLSServerTest
|
|||
stopServer();
|
||||
startProxy();
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
httpClient.start();
|
||||
|
||||
|
@ -443,7 +458,7 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testProxyClosesConnection(SslContextFactory scenario) throws Exception
|
||||
public void testProxyClosesConnection(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
startTLSServer(new ServerHandler());
|
||||
|
@ -456,26 +471,25 @@ public class ForwardProxyTLSServerTest
|
|||
}
|
||||
});
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
|
||||
httpClient.start();
|
||||
|
||||
assertThrows(ExecutionException.class, ()->{
|
||||
httpClient.newRequest("localhost", serverConnector.getLocalPort())
|
||||
.scheme(HttpScheme.HTTPS.asString())
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send();
|
||||
});
|
||||
assertThrows(ExecutionException.class, () ->
|
||||
httpClient.newRequest("localhost", serverConnector.getLocalPort())
|
||||
.scheme(HttpScheme.HTTPS.asString())
|
||||
.timeout(5, TimeUnit.SECONDS)
|
||||
.send());
|
||||
|
||||
httpClient.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testProxyAuthentication(SslContextFactory scenario) throws Exception
|
||||
public void testProxyAuthentication(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
final String realm = "test-realm";
|
||||
String realm = "test-realm";
|
||||
testProxyAuthentication(realm, new ConnectHandler()
|
||||
{
|
||||
@Override
|
||||
|
@ -496,10 +510,10 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testProxyAuthenticationWithResponseContent(SslContextFactory scenario) throws Exception
|
||||
public void testProxyAuthenticationWithResponseContent(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
final String realm = "test-realm";
|
||||
String realm = "test-realm";
|
||||
testProxyAuthentication(realm, new ConnectHandler()
|
||||
{
|
||||
@Override
|
||||
|
@ -521,10 +535,10 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testProxyAuthenticationWithIncludedAddressWithResponseContent(SslContextFactory scenario) throws Exception
|
||||
public void testProxyAuthenticationWithIncludedAddressWithResponseContent(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
final String realm = "test-realm";
|
||||
String realm = "test-realm";
|
||||
testProxyAuthentication(realm, new ConnectHandler()
|
||||
{
|
||||
@Override
|
||||
|
@ -546,16 +560,16 @@ public class ForwardProxyTLSServerTest
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("scenarios")
|
||||
public void testProxyAuthenticationClosesConnection(SslContextFactory scenario) throws Exception
|
||||
public void testProxyAuthenticationClosesConnection(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
final String realm = "test-realm";
|
||||
String realm = "test-realm";
|
||||
testProxyAuthentication(realm, new ConnectHandler()
|
||||
{
|
||||
@Override
|
||||
protected boolean handleAuthentication(HttpServletRequest request, HttpServletResponse response, String address)
|
||||
{
|
||||
final String header = request.getHeader(HttpHeader.PROXY_AUTHORIZATION.toString());
|
||||
String header = request.getHeader(HttpHeader.PROXY_AUTHORIZATION.toString());
|
||||
if (header == null || !header.startsWith("Basic "))
|
||||
{
|
||||
response.setHeader(HttpHeader.PROXY_AUTHENTICATE.toString(), "Basic realm=\"" + realm + "\"");
|
||||
|
@ -580,7 +594,7 @@ public class ForwardProxyTLSServerTest
|
|||
startTLSServer(new ServerHandler());
|
||||
startProxy(connectHandler);
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
HttpProxy httpProxy = newHttpProxy();
|
||||
if (includeAddress)
|
||||
httpProxy.getIncludedAddresses().add("localhost:" + serverConnector.getLocalPort());
|
||||
|
@ -614,7 +628,7 @@ public class ForwardProxyTLSServerTest
|
|||
@MethodSource("scenarios")
|
||||
@Tag("Unstable")
|
||||
@Disabled("External Proxy Server no longer stable enough for testing")
|
||||
public void testExternalProxy(SslContextFactory scenario) throws Exception
|
||||
public void testExternalProxy(SslContextFactory.Server scenario) throws Exception
|
||||
{
|
||||
init(scenario);
|
||||
// Free proxy server obtained from http://hidemyass.com/proxy-list/
|
||||
|
@ -629,10 +643,7 @@ public class ForwardProxyTLSServerTest
|
|||
assumeTrue(false, "Environment not able to connect to proxy service");
|
||||
}
|
||||
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
sslContextFactory.start();
|
||||
|
||||
HttpClient httpClient = new HttpClient(newClientSslContextFactory());
|
||||
HttpClient httpClient = newHttpClient();
|
||||
httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(proxyHost, proxyPort));
|
||||
httpClient.start();
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites
|
||||
-->
|
||||
|
||||
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
|
||||
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
|
||||
<Set name="Provider"><Property name="jetty.sslContext.provider"/></Set>
|
||||
<Set name="KeyStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" default="etc/keystore"/></Set>
|
||||
<Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
|
||||
|
|
|
@ -111,7 +111,7 @@ public abstract class AbstractConnectionFactory extends ContainerLifeCycle imple
|
|||
return String.format("%s@%x%s",this.getClass().getSimpleName(),hashCode(),getProtocols());
|
||||
}
|
||||
|
||||
public static ConnectionFactory[] getFactories(SslContextFactory sslContextFactory, ConnectionFactory... factories)
|
||||
public static ConnectionFactory[] getFactories(SslContextFactory.Server sslContextFactory, ConnectionFactory... factories)
|
||||
{
|
||||
factories=ArrayUtil.removeNulls(factories);
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
@ -63,7 +62,7 @@ public class LocalConnector extends AbstractConnector
|
|||
this(server, null, null, null, -1, new HttpConnectionFactory());
|
||||
}
|
||||
|
||||
public LocalConnector(Server server, SslContextFactory sslContextFactory)
|
||||
public LocalConnector(Server server, SslContextFactory.Server sslContextFactory)
|
||||
{
|
||||
this(server, null, null, null, -1,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
|
||||
}
|
||||
|
@ -73,7 +72,7 @@ public class LocalConnector extends AbstractConnector
|
|||
this(server, null, null, null, -1, connectionFactory);
|
||||
}
|
||||
|
||||
public LocalConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory sslContextFactory)
|
||||
public LocalConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory.Server sslContextFactory)
|
||||
{
|
||||
this(server, null, null, null, -1, AbstractConnectionFactory.getFactories(sslContextFactory,connectionFactory));
|
||||
}
|
||||
|
@ -113,7 +112,7 @@ public class LocalConnector extends AbstractConnector
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void accept(int acceptorID) throws IOException, InterruptedException
|
||||
protected void accept(int acceptorID) throws InterruptedException
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("accepting {}", acceptorID);
|
||||
|
@ -401,7 +400,7 @@ public class LocalConnector extends AbstractConnector
|
|||
|
||||
HttpParser parser = new HttpParser(handler);
|
||||
parser.setHeadResponse(head);
|
||||
try(ByteArrayOutputStream2 bout = new ByteArrayOutputStream2();)
|
||||
try(ByteArrayOutputStream2 bout = new ByteArrayOutputStream2())
|
||||
{
|
||||
loop: while(true)
|
||||
{
|
||||
|
@ -416,7 +415,7 @@ public class LocalConnector extends AbstractConnector
|
|||
{
|
||||
parser.atEOF();
|
||||
parser.parseNext(BufferUtil.EMPTY_BUFFER);
|
||||
break loop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class NetworkTrafficServerConnector extends ServerConnector
|
|||
this(server, null, null, null, 0, 0, new HttpConnectionFactory());
|
||||
}
|
||||
|
||||
public NetworkTrafficServerConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory sslContextFactory)
|
||||
public NetworkTrafficServerConnector(Server server, ConnectionFactory connectionFactory, SslContextFactory.Server sslContextFactory)
|
||||
{
|
||||
super(server, sslContextFactory, connectionFactory);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public class NetworkTrafficServerConnector extends ServerConnector
|
|||
super(server, executor, scheduler, pool, acceptors, selectors, factories);
|
||||
}
|
||||
|
||||
public NetworkTrafficServerConnector(Server server, SslContextFactory sslContextFactory)
|
||||
public NetworkTrafficServerConnector(Server server, SslContextFactory.Server sslContextFactory)
|
||||
{
|
||||
super(server, sslContextFactory);
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ public class ServerConnector extends AbstractNetworkConnector
|
|||
*/
|
||||
public ServerConnector(
|
||||
@Name("server") Server server,
|
||||
@Name("sslContextFactory") SslContextFactory sslContextFactory)
|
||||
@Name("sslContextFactory") SslContextFactory.Server sslContextFactory)
|
||||
{
|
||||
this(server,null,null,null,-1,-1,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ public class ServerConnector extends AbstractNetworkConnector
|
|||
@Name("server") Server server,
|
||||
@Name("acceptors") int acceptors,
|
||||
@Name("selectors") int selectors,
|
||||
@Name("sslContextFactory") SslContextFactory sslContextFactory)
|
||||
@Name("sslContextFactory") SslContextFactory.Server sslContextFactory)
|
||||
{
|
||||
this(server,null,null,null,acceptors,selectors,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ public class ServerConnector extends AbstractNetworkConnector
|
|||
*/
|
||||
public ServerConnector(
|
||||
@Name("server") Server server,
|
||||
@Name("sslContextFactory") SslContextFactory sslContextFactory,
|
||||
@Name("sslContextFactory") SslContextFactory.Server sslContextFactory,
|
||||
@Name("factories") ConnectionFactory... factories)
|
||||
{
|
||||
this(server, null, null, null, -1, -1, AbstractConnectionFactory.getFactories(sslContextFactory, factories));
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
|
||||
public class SslConnectionFactory extends AbstractConnectionFactory
|
||||
{
|
||||
private final SslContextFactory _sslContextFactory;
|
||||
private final SslContextFactory.Server _sslContextFactory;
|
||||
private final String _nextProtocol;
|
||||
private boolean _directBuffersForEncryption = false;
|
||||
private boolean _directBuffersForDecryption = false;
|
||||
|
@ -50,15 +50,15 @@ public class SslConnectionFactory extends AbstractConnectionFactory
|
|||
this(null,nextProtocol);
|
||||
}
|
||||
|
||||
public SslConnectionFactory(@Name("sslContextFactory") SslContextFactory factory, @Name("next") String nextProtocol)
|
||||
public SslConnectionFactory(@Name("sslContextFactory") SslContextFactory.Server factory, @Name("next") String nextProtocol)
|
||||
{
|
||||
super("SSL");
|
||||
_sslContextFactory=factory==null?new SslContextFactory():factory;
|
||||
_nextProtocol=nextProtocol;
|
||||
_sslContextFactory = factory == null ? new SslContextFactory.Server() : factory;
|
||||
_nextProtocol = nextProtocol;
|
||||
addBean(_sslContextFactory);
|
||||
}
|
||||
|
||||
public SslContextFactory getSslContextFactory()
|
||||
public SslContextFactory.Server getSslContextFactory()
|
||||
{
|
||||
return _sslContextFactory;
|
||||
}
|
||||
|
|
|
@ -1618,9 +1618,13 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
|
|||
|
||||
if (getServer() != null && (getServer().isStarting() || getServer().isStarted()))
|
||||
{
|
||||
Handler[] contextCollections = getServer().getChildHandlersByClass(ContextHandlerCollection.class);
|
||||
for (int h = 0; contextCollections != null && h < contextCollections.length; h++)
|
||||
((ContextHandlerCollection)contextCollections[h]).mapContexts();
|
||||
Class<ContextHandlerCollection> handlerClass = ContextHandlerCollection.class;
|
||||
Handler[] contextCollections = getServer().getChildHandlersByClass(handlerClass);
|
||||
if (contextCollections != null)
|
||||
{
|
||||
for (Handler contextCollection : contextCollections)
|
||||
handlerClass.cast(contextCollection).mapContexts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,7 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -36,15 +35,16 @@ import org.eclipse.jetty.server.HttpChannelState;
|
|||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.ArrayTernaryTrie;
|
||||
import org.eclipse.jetty.util.ArrayUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Trie;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.ManagedOperation;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.thread.SerializedExecutor;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** ContextHandlerCollection.
|
||||
*
|
||||
/**
|
||||
* This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a
|
||||
* Map of contexts to it's contained handlers based
|
||||
* on the context path and virtual hosts of any contained {@link org.eclipse.jetty.server.handler.ContextHandler}s.
|
||||
|
@ -57,9 +57,9 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
public class ContextHandlerCollection extends HandlerCollection
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class);
|
||||
private final SerializedExecutor _serializedExecutor = new SerializedExecutor();
|
||||
|
||||
private final ConcurrentMap<ContextHandler,Handler> _contextBranches = new ConcurrentHashMap<>();
|
||||
private volatile Trie<Map.Entry<String,Branch[]>> _pathBranches;
|
||||
@Deprecated
|
||||
private Class<? extends ContextHandler> _contextClass = ContextHandler.class;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -71,43 +71,57 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
/* ------------------------------------------------------------ */
|
||||
public ContextHandlerCollection(ContextHandler... contexts)
|
||||
{
|
||||
super(true,contexts);
|
||||
super(true);
|
||||
setHandlers(contexts);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Remap the context paths.
|
||||
* Remap the contexts. Normally this is not required as context
|
||||
* mapping is maintained as a side effect of {@link #setHandlers(Handler[])}
|
||||
* However, if configuration changes in the deep handler structure (eg contextpath is changed), then
|
||||
* this call will trigger a remapping.
|
||||
* This method is mutually excluded from {@link #deployHandler(Handler, Callback)} and
|
||||
* {@link #undeployHandler(Handler, Callback)}
|
||||
*/
|
||||
@ManagedOperation("update the mapping of context path to context")
|
||||
@ManagedOperation("Update the mapping of context path to context")
|
||||
public void mapContexts()
|
||||
{
|
||||
_contextBranches.clear();
|
||||
|
||||
Handler[] handlers = getHandlers();
|
||||
if (handlers==null)
|
||||
_serializedExecutor.execute(()->
|
||||
{
|
||||
_pathBranches=new ArrayTernaryTrie<>(false,16);
|
||||
return;
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
Handlers handlers = _handlers.get();
|
||||
if (handlers==null)
|
||||
break;
|
||||
if (updateHandlers(handlers, newHandlers(handlers.getHandlers())))
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected Handlers newHandlers(Handler[] handlers)
|
||||
{
|
||||
if (handlers==null || handlers.length==0)
|
||||
return null;
|
||||
|
||||
// Create map of contextPath to handler Branch
|
||||
Map<String,Branch[]> map = new HashMap<>();
|
||||
// A branch is a Handler that could contain 0 or more ContextHandlers
|
||||
Map<String,Branch[]> path2Branches = new HashMap<>();
|
||||
for (Handler handler:handlers)
|
||||
{
|
||||
Branch branch=new Branch(handler);
|
||||
for (String contextPath : branch.getContextPaths())
|
||||
{
|
||||
Branch[] branches=map.get(contextPath);
|
||||
map.put(contextPath, ArrayUtil.addToArray(branches, branch, Branch.class));
|
||||
Branch[] branches=path2Branches.get(contextPath);
|
||||
path2Branches.put(contextPath, ArrayUtil.addToArray(branches, branch, Branch.class));
|
||||
}
|
||||
|
||||
for (ContextHandler context : branch.getContextHandlers())
|
||||
_contextBranches.putIfAbsent(context, branch.getHandler());
|
||||
}
|
||||
|
||||
// Sort the branches so those with virtual hosts are considered before those without
|
||||
for (Map.Entry<String,Branch[]> entry: map.entrySet())
|
||||
// Sort the branches for each contextPath so those with virtual hosts are considered before those without
|
||||
for (Map.Entry<String,Branch[]> entry: path2Branches.entrySet())
|
||||
{
|
||||
Branch[] branches=entry.getValue();
|
||||
Branch[] sorted=new Branch[branches.length];
|
||||
|
@ -123,69 +137,56 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
|
||||
// Loop until we have a big enough trie to hold all the context paths
|
||||
int capacity=512;
|
||||
Trie<Map.Entry<String,Branch[]>> trie;
|
||||
Mapping mapping;
|
||||
loop: while(true)
|
||||
{
|
||||
trie=new ArrayTernaryTrie<>(false,capacity);
|
||||
for (Map.Entry<String,Branch[]> entry: map.entrySet())
|
||||
mapping = new Mapping(handlers, capacity);
|
||||
for (Map.Entry<String,Branch[]> entry: path2Branches.entrySet())
|
||||
{
|
||||
if (!trie.put(entry.getKey().substring(1),entry))
|
||||
if (!mapping._pathBranches.put(entry.getKey().substring(1),entry))
|
||||
{
|
||||
capacity+=512;
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
break loop;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
for (String ctx : trie.keySet())
|
||||
LOG.debug("{}->{}",ctx,Arrays.asList(trie.get(ctx).getValue()));
|
||||
for (String ctx : mapping._pathBranches.keySet())
|
||||
LOG.debug("{}->{}",ctx,Arrays.asList(mapping._pathBranches.get(ctx).getValue()));
|
||||
}
|
||||
_pathBranches=trie;
|
||||
|
||||
// add new context branches to concurrent map
|
||||
for (Branch[] branches: path2Branches.values())
|
||||
{
|
||||
for (Branch branch : branches)
|
||||
{
|
||||
for (ContextHandler context : branch.getContextHandlers())
|
||||
mapping._contextBranches.put(context, branch.getHandler());
|
||||
}
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see org.eclipse.jetty.server.server.handler.HandlerCollection#setHandlers(org.eclipse.jetty.server.server.Handler[])
|
||||
*/
|
||||
@Override
|
||||
public void setHandlers(Handler[] handlers)
|
||||
{
|
||||
super.setHandlers(handlers);
|
||||
if (isStarted())
|
||||
mapContexts();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
mapContexts();
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
|
||||
*/
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
Handler[] handlers = getHandlers();
|
||||
if (handlers==null || handlers.length==0)
|
||||
Handlers handlers = _handlers.get();
|
||||
if (handlers==null)
|
||||
return;
|
||||
|
||||
Mapping mapping = (Mapping)handlers;
|
||||
HttpChannelState async = baseRequest.getHttpChannelState();
|
||||
if (async.isAsync())
|
||||
{
|
||||
ContextHandler context=async.getContextHandler();
|
||||
if (context!=null)
|
||||
{
|
||||
Handler branch = _contextBranches.get(context);
|
||||
Handler branch = mapping._contextBranches.get(context);
|
||||
|
||||
if (branch==null)
|
||||
context.handle(target,baseRequest,request, response);
|
||||
|
@ -195,19 +196,19 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
}
|
||||
|
||||
// data structure which maps a request to a context; first-best match wins
|
||||
// { context path => [ context ] }
|
||||
// }
|
||||
if (target.startsWith("/"))
|
||||
{
|
||||
Trie<Map.Entry<String,Branch[]>> pathBranches = mapping._pathBranches;
|
||||
if (pathBranches==null)
|
||||
return;
|
||||
|
||||
int limit = target.length()-1;
|
||||
|
||||
while (limit>=0)
|
||||
{
|
||||
// Get best match
|
||||
Map.Entry<String,Branch[]> branches = _pathBranches.getBest(target,1,limit);
|
||||
|
||||
|
||||
Map.Entry<String,Branch[]> branches = pathBranches.getBest(target,1,limit);
|
||||
|
||||
if (branches==null)
|
||||
break;
|
||||
|
||||
|
@ -227,10 +228,11 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
else
|
||||
{
|
||||
// This may not work in all circumstances... but then I think it should never be called
|
||||
for (int i=0;i<handlers.length;i++)
|
||||
if (mapping.getHandlers()==null)
|
||||
return;
|
||||
for (int i=0;i<mapping.getHandlers().length;i++)
|
||||
{
|
||||
handlers[i].handle(target,baseRequest, request, response);
|
||||
mapping.getHandlers()[i].handle(target,baseRequest, request, response);
|
||||
if ( baseRequest.isHandled())
|
||||
return;
|
||||
}
|
||||
|
@ -238,11 +240,15 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add a context handler.
|
||||
/**
|
||||
* Adds a context handler.
|
||||
*
|
||||
* @param contextPath The context path to add
|
||||
* @param resourceBase the base (root) Resource
|
||||
* @return the ContextHandler just added
|
||||
* @deprecated Unused convenience method no longer supported.
|
||||
*/
|
||||
@Deprecated
|
||||
public ContextHandler addContext(String contextPath,String resourceBase)
|
||||
{
|
||||
try
|
||||
|
@ -260,22 +266,90 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Thread safe deploy of a Handler.
|
||||
* <p>
|
||||
* This method is the equivalent of {@link #addHandler(Handler)},
|
||||
* but its execution is non-block and mutually excluded from all
|
||||
* other calls to {@link #deployHandler(Handler, Callback)} and
|
||||
* {@link #undeployHandler(Handler, Callback)}.
|
||||
* The handler may be added after this call returns.
|
||||
* </p>
|
||||
* @param handler the handler to deploy
|
||||
* @param callback Called after handler has been added
|
||||
*/
|
||||
public void deployHandler(Handler handler, Callback callback)
|
||||
{
|
||||
if (handler.getServer()!=getServer())
|
||||
handler.setServer(getServer());
|
||||
|
||||
_serializedExecutor.execute(new SerializedExecutor.ErrorHandlingTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
addHandler(handler);
|
||||
callback.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Throwable throwable)
|
||||
{
|
||||
callback.failed(throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Thread safe undeploy of a Handler.
|
||||
* <p>
|
||||
* This method is the equivalent of {@link #removeHandler(Handler)},
|
||||
* but its execution is non-block and mutually excluded from all
|
||||
* other calls to {@link #deployHandler(Handler,Callback)} and
|
||||
* {@link #undeployHandler(Handler,Callback)}.
|
||||
* The handler may be removed after this call returns.
|
||||
* </p>
|
||||
* @param handler The handler to undeploy
|
||||
* @param callback Called after handler has been removed
|
||||
*/
|
||||
public void undeployHandler(Handler handler, Callback callback)
|
||||
{
|
||||
_serializedExecutor.execute(new SerializedExecutor.ErrorHandlingTask()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
removeHandler(handler);
|
||||
callback.succeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Throwable throwable)
|
||||
{
|
||||
callback.failed(throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The class to use to add new Contexts
|
||||
* @deprecated Unused convenience mechanism not used.
|
||||
*/
|
||||
@Deprecated
|
||||
public Class<?> getContextClass()
|
||||
{
|
||||
return _contextClass;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param contextClass The class to use to add new Contexts
|
||||
* @deprecated Unused convenience mechanism not used.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setContextClass(Class<? extends ContextHandler> contextClass)
|
||||
{
|
||||
if (contextClass ==null || !(ContextHandler.class.isAssignableFrom(contextClass)))
|
||||
|
@ -342,5 +416,18 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
private static class Mapping extends Handlers
|
||||
{
|
||||
private final Map<ContextHandler,Handler> _contextBranches = new HashMap<>();
|
||||
private final Trie<Map.Entry<String,Branch[]>> _pathBranches;
|
||||
|
||||
private Mapping(Handler[] handlers, int capacity)
|
||||
{
|
||||
super(handlers);
|
||||
_pathBranches = new ArrayTernaryTrie<>(false, capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.server.handler;
|
|||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -47,7 +48,7 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
public class HandlerCollection extends AbstractHandlerContainer
|
||||
{
|
||||
private final boolean _mutableWhenRunning;
|
||||
private volatile Handler[] _handlers;
|
||||
protected final AtomicReference<Handlers> _handlers = new AtomicReference<>();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public HandlerCollection()
|
||||
|
@ -71,72 +72,93 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the handlers.
|
||||
* @return the array of handlers.
|
||||
*/
|
||||
@Override
|
||||
@ManagedAttribute(value="Wrapped handlers", readonly=true)
|
||||
public Handler[] getHandlers()
|
||||
{
|
||||
return _handlers;
|
||||
Handlers handlers = _handlers.get();
|
||||
return handlers==null ? null : handlers._handlers;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param handlers The handlers to set.
|
||||
* @param handlers the array of handlers to set.
|
||||
*/
|
||||
public void setHandlers(Handler[] handlers)
|
||||
{
|
||||
if (!_mutableWhenRunning && isStarted())
|
||||
throw new IllegalStateException(STARTED);
|
||||
|
||||
if (handlers!=null)
|
||||
while(true)
|
||||
{
|
||||
// check for loops
|
||||
for (Handler handler:handlers)
|
||||
if (handler == this || (handler instanceof HandlerContainer &&
|
||||
Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this)))
|
||||
throw new IllegalStateException("setHandler loop");
|
||||
|
||||
// Set server
|
||||
for (Handler handler:handlers)
|
||||
if (handler.getServer()!=getServer())
|
||||
handler.setServer(getServer());
|
||||
if (updateHandlers(_handlers.get(), newHandlers(handlers)))
|
||||
break;
|
||||
}
|
||||
Handler[] old=_handlers;;
|
||||
_handlers = handlers;
|
||||
updateBeans(old, handlers);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see Handler#handle(String, Request, HttpServletRequest, HttpServletResponse)
|
||||
*/
|
||||
protected Handlers newHandlers(Handler[] handlers)
|
||||
{
|
||||
if (handlers==null || handlers.length==0)
|
||||
return null;
|
||||
return new Handlers(handlers);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected boolean updateHandlers(Handlers old, Handlers handlers)
|
||||
{
|
||||
if (handlers!=null)
|
||||
{
|
||||
// check for loops
|
||||
for (Handler handler:handlers._handlers)
|
||||
if (handler == this || (handler instanceof HandlerContainer &&
|
||||
Arrays.asList(((HandlerContainer)handler).getChildHandlers()).contains(this)))
|
||||
throw new IllegalStateException("setHandler loop");
|
||||
|
||||
// Set server
|
||||
for (Handler handler:handlers._handlers)
|
||||
if (handler.getServer()!=getServer())
|
||||
handler.setServer(getServer());
|
||||
}
|
||||
|
||||
if (_handlers.compareAndSet(old, handlers))
|
||||
{
|
||||
Handler[] oldBeans = old == null ? null : old._handlers;
|
||||
Handler[] newBeans = handlers == null ? null : handlers._handlers;
|
||||
updateBeans(oldBeans, newBeans);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
if (_handlers!=null && isStarted())
|
||||
if (isStarted())
|
||||
{
|
||||
MultiException mex=null;
|
||||
Handlers handlers = _handlers.get();
|
||||
if (handlers==null)
|
||||
return;
|
||||
|
||||
for (int i=0;i<_handlers.length;i++)
|
||||
MultiException mex=null;
|
||||
for (Handler handler : handlers._handlers)
|
||||
{
|
||||
try
|
||||
{
|
||||
_handlers[i].handle(target,baseRequest, request, response);
|
||||
handler.handle(target, baseRequest, request, response);
|
||||
}
|
||||
catch(IOException e)
|
||||
catch (IOException | RuntimeException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(RuntimeException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
if (mex==null)
|
||||
mex=new MultiException();
|
||||
if (mex == null)
|
||||
mex = new MultiException();
|
||||
mex.add(e);
|
||||
}
|
||||
}
|
||||
|
@ -147,37 +169,54 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
else
|
||||
throw new ServletException(mex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Add a handler.
|
||||
/**
|
||||
* Adds a handler.
|
||||
* This implementation adds the passed handler to the end of the existing collection of handlers.
|
||||
* @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
|
||||
* If the handler is already added, it is removed and readded
|
||||
*/
|
||||
public void addHandler(Handler handler)
|
||||
{
|
||||
setHandlers(ArrayUtil.addToArray(getHandlers(), handler, Handler.class));
|
||||
while(true)
|
||||
{
|
||||
Handlers old = _handlers.get();
|
||||
Handlers handlers = newHandlers(ArrayUtil.addToArray(old==null?null:ArrayUtil.removeFromArray(old._handlers, handler), handler, Handler.class));
|
||||
if (updateHandlers(old,handlers))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Prepend a handler.
|
||||
/**
|
||||
* Prepends a handler.
|
||||
* This implementation adds the passed handler to the start of the existing collection of handlers.
|
||||
* @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
|
||||
*/
|
||||
public void prependHandler(Handler handler)
|
||||
{
|
||||
setHandlers(ArrayUtil.prependToArray(handler, getHandlers(), Handler.class));
|
||||
while(true)
|
||||
{
|
||||
Handlers old = _handlers.get();
|
||||
Handlers handlers = newHandlers(ArrayUtil.prependToArray(handler, old==null?null:old._handlers, Handler.class));
|
||||
if (updateHandlers(old,handlers))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void removeHandler(Handler handler)
|
||||
{
|
||||
Handler[] handlers = getHandlers();
|
||||
|
||||
if (handlers!=null && handlers.length>0 )
|
||||
setHandlers(ArrayUtil.removeFromArray(handlers, handler));
|
||||
while(true)
|
||||
{
|
||||
Handlers old = _handlers.get();
|
||||
if (old==null || old._handlers.length==0)
|
||||
break;
|
||||
Handlers handlers = newHandlers(ArrayUtil.removeFromArray(old._handlers, handler));
|
||||
if (updateHandlers(old,handlers))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -196,10 +235,28 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
{
|
||||
if (!isStopped())
|
||||
throw new IllegalStateException("!STOPPED");
|
||||
Handler[] children=getChildHandlers();
|
||||
Handler[] children = getChildHandlers();
|
||||
setHandlers(null);
|
||||
for (Handler child: children)
|
||||
child.destroy();
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
protected static class Handlers
|
||||
{
|
||||
private final Handler[] _handlers;
|
||||
|
||||
protected Handlers(Handler[] handlers)
|
||||
{
|
||||
this._handlers = handlers;
|
||||
}
|
||||
|
||||
public Handler[] getHandlers()
|
||||
{
|
||||
return _handlers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
|
@ -170,7 +170,7 @@ public class ConnectionOpenCloseTest extends AbstractHttpTest
|
|||
@DisabledIfSystemProperty(named = "env", matches = "ci") // TODO: SLOW, needs review
|
||||
public void testSSLOpenRequestClose() throws Exception
|
||||
{
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
sslContextFactory.setKeyStoreResource(Resource.newResource(keystore));
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
|
|
|
@ -52,7 +52,7 @@ public class OptionalSslConnectionTest
|
|||
server = new Server(serverThreads);
|
||||
|
||||
String keystore = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystore);
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
@ -113,7 +113,7 @@ public class OptionalSslConnectionTest
|
|||
}
|
||||
|
||||
// Then try a SSL connection.
|
||||
SslContextFactory sslContextFactory = new SslContextFactory(true);
|
||||
SslContextFactory sslContextFactory = new SslContextFactory.Client(true);
|
||||
sslContextFactory.start();
|
||||
try (Socket ssl = sslContextFactory.newSslSocket())
|
||||
{
|
||||
|
|
|
@ -18,17 +18,17 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -82,6 +82,7 @@ public class ProxyConnectionTest
|
|||
}
|
||||
|
||||
@Test
|
||||
@Tag("ipv6")
|
||||
public void testIPv6() throws Exception
|
||||
{
|
||||
String response=_connector.getResponse("PROXY UNKNOWN eeee:eeee:eeee:eeee:eeee:eeee:eeee:eeee ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 65535 65535\r\n"+
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -33,7 +28,6 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -56,12 +50,16 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ThreadStarvationTest
|
||||
{
|
||||
final static int BUFFER_SIZE=1024*1024;
|
||||
|
@ -82,14 +80,14 @@ public class ThreadStarvationTest
|
|||
List<Scenario> params = new ArrayList<>();
|
||||
|
||||
// HTTP
|
||||
ConnectorProvider http = (server, acceptors, selectors) -> new ServerConnector(server, acceptors, selectors);
|
||||
ClientSocketProvider httpClient = (host, port) -> new Socket(host, port);
|
||||
ConnectorProvider http = ServerConnector::new;
|
||||
ClientSocketProvider httpClient = Socket::new;
|
||||
params.add(new Scenario("http", http, httpClient));
|
||||
|
||||
// HTTPS/SSL/TLS
|
||||
ConnectorProvider https = (server, acceptors, selectors) -> {
|
||||
Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystorePath.toString());
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
@ -98,8 +96,7 @@ public class ThreadStarvationTest
|
|||
ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
|
||||
|
||||
HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory();
|
||||
ServerConnector connector = new ServerConnector(server,(Executor)null,(Scheduler)null,
|
||||
pool, acceptors, selectors,
|
||||
ServerConnector connector = new ServerConnector(server, null, null, pool, acceptors, selectors,
|
||||
AbstractConnectionFactory.getFactories(sslContextFactory,httpConnectionFactory));
|
||||
SecureRequestCustomizer secureRequestCustomer = new SecureRequestCustomizer();
|
||||
secureRequestCustomer.setSslSessionAttribute("SSL_SESSION");
|
||||
|
@ -312,8 +309,8 @@ public class ThreadStarvationTest
|
|||
// Read Response
|
||||
long bodyCount = 0;
|
||||
long len;
|
||||
|
||||
byte buf[] = new byte[1024];
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -343,7 +340,7 @@ public class ThreadStarvationTest
|
|||
for (Future<Long> responseFut : responses)
|
||||
{
|
||||
Long bodyCount = responseFut.get();
|
||||
assertThat(bodyCount.longValue(), is(expected));
|
||||
assertThat(bodyCount, is(expected));
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -18,16 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
|
@ -41,9 +31,18 @@ import org.eclipse.jetty.server.LocalConnector;
|
|||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class ContextHandlerCollectionTest
|
||||
{
|
||||
@Test
|
||||
|
@ -214,7 +213,7 @@ public class ContextHandlerCollectionTest
|
|||
IsHandledHandler handler = (IsHandledHandler)context.getHandler();
|
||||
|
||||
context.setVirtualHosts(contextHosts);
|
||||
// trigger this manually; it's supposed to be called when adding the handler
|
||||
// trigger this manually
|
||||
handlerCollection.mapContexts();
|
||||
|
||||
for(String host : requestHosts)
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -31,14 +26,11 @@ import java.net.HttpURLConnection;
|
|||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyStore;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -53,21 +45,18 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class DebugHandlerTest
|
||||
{
|
||||
public final static HostnameVerifier __hostnameverifier = new HostnameVerifier()
|
||||
{
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
public final static HostnameVerifier __hostnameverifier = (hostname, session) -> true;
|
||||
|
||||
private SSLContext sslContext;
|
||||
private Server server;
|
||||
|
@ -77,7 +66,6 @@ public class DebugHandlerTest
|
|||
private DebugHandler debugHandler;
|
||||
private ByteArrayOutputStream capturedLog;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@BeforeEach
|
||||
public void startServer() throws Exception
|
||||
{
|
||||
|
@ -88,16 +76,14 @@ public class DebugHandlerTest
|
|||
server.addConnector(httpConnector);
|
||||
|
||||
File keystorePath = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystorePath.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
sslContextFactory.setTrustStorePath(keystorePath.getAbsolutePath());
|
||||
sslContextFactory.setTrustStorePassword("storepwd");
|
||||
ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
|
||||
ServerConnector sslConnector = new ServerConnector(server,
|
||||
(Executor)null,
|
||||
(Scheduler)null, pool, 1, 1,
|
||||
ServerConnector sslConnector = new ServerConnector(server, null, null, pool, 1, 1,
|
||||
AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
|
||||
|
||||
server.addConnector(sslConnector);
|
||||
|
@ -108,7 +94,7 @@ public class DebugHandlerTest
|
|||
debugHandler.setHandler(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
response.setStatus(HttpStatus.OK_200);
|
||||
|
|
|
@ -167,7 +167,7 @@ public class ResourceHandlerTest
|
|||
_local.getResponse("GET /resource/ HTTP/1.0\r\n\r\n"));
|
||||
assertThat(response.getStatus(),equalTo(200));
|
||||
assertThat(response.getContent(),containsString("jetty-dir.css"));
|
||||
assertThat(response.getContent(),containsString("<H1>Directory: /resource/"));
|
||||
assertThat(response.getContent(),containsString("Directory: /resource/"));
|
||||
assertThat(response.getContent(),containsString("big.txt"));
|
||||
assertThat(response.getContent(),containsString("bigger.txt"));
|
||||
assertThat(response.getContent(),containsString("directory"));
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.handler;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -55,6 +51,10 @@ import org.junit.jupiter.api.AfterAll;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class SecuredRedirectHandlerTest
|
||||
{
|
||||
private static Server server;
|
||||
|
@ -68,7 +68,7 @@ public class SecuredRedirectHandlerTest
|
|||
{
|
||||
// Setup SSL
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystore.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
|
|
@ -27,7 +27,6 @@ import java.net.Socket;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -37,7 +36,6 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -48,7 +46,7 @@ public class SSLCloseTest
|
|||
public void testClose() throws Exception
|
||||
{
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStoreResource(Resource.newResource(keystore));
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
|
|
@ -23,12 +23,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.ssl;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -63,6 +57,12 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ public class SSLEngineTest
|
|||
public void startServer() throws Exception
|
||||
{
|
||||
String keystore = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystore);
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.ssl;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -30,7 +27,6 @@ import java.net.Socket;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
@ -46,6 +42,9 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.api.condition.DisabledOnJre;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
// Only in JDK 11 is possible to use SSLSocket.shutdownOutput().
|
||||
@DisabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10})
|
||||
public class SSLReadEOFAfterResponseTest
|
||||
|
@ -54,7 +53,7 @@ public class SSLReadEOFAfterResponseTest
|
|||
public void testReadEOFAfterResponse() throws Exception
|
||||
{
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStoreResource(Resource.newResource(keystore));
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
@ -70,7 +69,7 @@ public class SSLReadEOFAfterResponseTest
|
|||
server.setHandler(new AbstractHandler.ErrorDispatchHandler()
|
||||
{
|
||||
@Override
|
||||
protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
protected void doNonErrorHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||
{
|
||||
// First: read the whole content.
|
||||
InputStream input = request.getInputStream();
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.ssl;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -53,6 +50,9 @@ import org.junit.jupiter.api.AfterAll;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
public class SSLSelectChannelConnectorLoadTest
|
||||
{
|
||||
private static Server server;
|
||||
|
@ -63,7 +63,7 @@ public class SSLSelectChannelConnectorLoadTest
|
|||
public static void startServer() throws Exception
|
||||
{
|
||||
String keystorePath = System.getProperty("basedir", ".") + "/src/test/resources/keystore";
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystorePath);
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.ssl;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isEmptyOrNullString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.condition.OS.WINDOWS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
@ -62,11 +54,19 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
|||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.condition.DisabledOnOs;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isEmptyOrNullString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.condition.OS.WINDOWS;
|
||||
|
||||
/**
|
||||
* HttpServer Tester.
|
||||
*/
|
||||
|
@ -83,7 +83,7 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
|||
public void init() throws Exception
|
||||
{
|
||||
String keystorePath = MavenTestingUtils.getTestResourcePath("keystore").toString();
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystorePath);
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.server.ssl;
|
||||
|
||||
import static java.time.Duration.ofSeconds;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -51,6 +49,8 @@ import org.junit.jupiter.api.Disabled;
|
|||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static java.time.Duration.ofSeconds;
|
||||
|
||||
@Tag("Unstable")
|
||||
@Disabled
|
||||
public class SlowClientsTest
|
||||
|
@ -61,7 +61,7 @@ public class SlowClientsTest
|
|||
public void testSlowClientsWithSmallThreadPool() throws Exception
|
||||
{
|
||||
File keystore = MavenTestingUtils.getTestResourceFile("keystore");
|
||||
SslContextFactory sslContextFactory = new SslContextFactory();
|
||||
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
|
||||
sslContextFactory.setKeyStorePath(keystore.getAbsolutePath());
|
||||
sslContextFactory.setKeyStorePassword("storepwd");
|
||||
sslContextFactory.setKeyManagerPassword("keypwd");
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue