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:
lachan-roberts 2019-04-09 18:18:50 +10:00
commit 002ecf526d
159 changed files with 3053 additions and 1662 deletions

2
Jenkinsfile vendored
View File

@ -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
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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
{

View File

@ -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()))

View File

@ -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");

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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));
}
}
}
}

View File

@ -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);

View File

@ -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);
}
}
}
}

View File

@ -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
*/

View File

@ -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

View File

@ -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()))
{

View File

@ -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");
}
}
}

View File

@ -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();

View File

@ -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;
}
};
}
}
}

View File

@ -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);

View File

@ -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);
}
}
}
}

View File

@ -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.

View File

@ -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);

View File

@ -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());

View File

@ -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();

View File

@ -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;
}

View File

@ -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();
});

View File

@ -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());

View File

@ -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);

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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

View File

@ -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())))
{

View File

@ -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);

View File

@ -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();

View File

@ -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");

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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");

View File

@ -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].

View File

@ -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>

View File

@ -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);

View File

@ -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

View File

@ -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());

View File

@ -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)

View File

@ -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();

View File

@ -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");

View File

@ -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());

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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);

View File

@ -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);
}

View File

@ -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/");

View File

@ -206,7 +206,7 @@ public class MaxConcurrentStreamsTest extends AbstractTest
}
}, promise, context);
}
}, null);
});
QueuedThreadPool clientExecutor = new QueuedThreadPool();
clientExecutor.setName("client");
client.setExecutor(clientExecutor);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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
*

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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();
}

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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()

View File

@ -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");

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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>

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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));

View File

@ -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;
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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())
{

View File

@ -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"+

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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"));

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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();

View File

@ -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");

View File

@ -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");

View File

@ -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