From b478332793b16bba98285290341ad165614253b6 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 20 Feb 2019 14:15:51 +1100 Subject: [PATCH 01/74] Issue #3361 thread set setHandlers protect handler mutation with synchronized. Correctly use copy-on-write semantics for accessing volatile Signed-off-by: Greg Wilkins --- .../handler/ContextHandlerCollection.java | 29 +++---- .../server/handler/HandlerCollection.java | 78 +++++++++++-------- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index 3beaa60f56c..f0b020808f0 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -155,9 +155,12 @@ public class ContextHandlerCollection extends HandlerCollection @Override public void setHandlers(Handler[] handlers) { - super.setHandlers(handlers); - if (isStarted()) - mapContexts(); + synchronized (this) + { + super.setHandlers(handlers); + if (isStarted()) + mapContexts(); + } } /* ------------------------------------------------------------ */ @@ -176,10 +179,6 @@ public class ContextHandlerCollection extends HandlerCollection @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - Handler[] handlers = getHandlers(); - if (handlers==null || handlers.length==0) - return; - HttpChannelState async = baseRequest.getHttpChannelState(); if (async.isAsync()) { @@ -196,19 +195,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> pathBranches = _pathBranches; + if (pathBranches==null) + return; + int limit = target.length()-1; while (limit>=0) { // Get best match - Map.Entry branches = _pathBranches.getBest(target,1,limit); - - + Map.Entry branches = pathBranches.getBest(target,1,limit); + if (branches==null) break; @@ -228,7 +227,9 @@ public class ContextHandlerCollection extends HandlerCollection } else { - // This may not work in all circumstances... but then I think it should never be called + Handler[] handlers = getHandlers(); + if (handlers==null) + return; for (int i=0;i0 ) - setHandlers(ArrayUtil.removeFromArray(handlers, handler)); + if (handlers!=null && handlers.length>0 ) + setHandlers(ArrayUtil.removeFromArray(handlers, handler)); + } } /* ------------------------------------------------------------ */ @@ -196,8 +208,12 @@ public class HandlerCollection extends AbstractHandlerContainer { if (!isStopped()) throw new IllegalStateException("!STOPPED"); - Handler[] children=getChildHandlers(); - setHandlers(null); + Handler[] children; + synchronized (this) + { + children = getChildHandlers(); + setHandlers(null); + } for (Handler child: children) child.destroy(); super.destroy(); From 4eb6094f82a2bad78feac3494556aad635825622 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 7 Mar 2019 16:04:18 +0100 Subject: [PATCH 02/74] Fixes #3411 - HttpClient does not timeout during multiple redirection. Removed timeout after copying the request in case of redirects (and authentications), to avoid that the timeout listener is notified of intermediate exchanges and resets the timeout. Signed-off-by: Simone Bordet --- .../client/AuthenticationProtocolHandler.java | 3 + .../org/eclipse/jetty/client/HttpClient.java | 4 +- .../jetty/client/HttpConversation.java | 10 +- .../eclipse/jetty/client/HttpDestination.java | 19 +- .../eclipse/jetty/client/HttpRedirector.java | 33 ++-- .../jetty/client/TimeoutCompleteListener.java | 13 +- .../org/eclipse/jetty/client/api/Request.java | 6 +- .../client/HttpClientAuthenticationTest.java | 173 ++++++++++++------ .../jetty/client/HttpClientRedirectTest.java | 123 +++++++++---- .../eclipse/jetty/client/HttpClientTest.java | 20 +- 10 files changed, 274 insertions(+), 130 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java index 1388931e233..a51aea42b9b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java @@ -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); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 7b9fa122f93..688ffbf569e 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -928,7 +928,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() @@ -937,7 +937,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) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java index a555d700965..3f57de2b9fc 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java @@ -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 exchanges = new ConcurrentLinkedDeque<>(); private volatile List 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; } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java index 58fde88a489..44a14a6bb9b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpDestination.java @@ -490,8 +490,12 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest exchanges.size(), connectionPool); } - - // 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); @@ -504,6 +508,9 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest @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; @@ -536,12 +543,16 @@ public abstract class HttpDestination extends ContainerLifeCycle implements Dest 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)); + } } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java index 24bdc74d8c6..9bd9f208a88 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java @@ -21,8 +21,10 @@ package org.eclipse.jetty.client; import java.net.URI; import java.net.URISyntaxException; import java.util.List; +import java.util.Objects; 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; @@ -101,11 +103,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 +146,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 @@ -157,6 +159,14 @@ public class HttpRedirector URI newURI = extractRedirectURI(response); if (newURI != null) { + boolean absolute = newURI.isAbsolute(); + URI uri = request.getURI(); + if (absolute && newURI.equals(uri) || + !absolute && Objects.equals(newURI.getPath(), uri.getPath())) + { + fail(request, response, new HttpResponseException("Redirect to same URI: " + location, response)); + return null; + } if (LOG.isDebugEnabled()) LOG.debug("Redirecting to {} (Location: {})", newURI, location); return redirect(request, response, listener, newURI); @@ -292,7 +302,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 +321,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); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java b/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java index ced60b57239..7a3121a755b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/TimeoutCompleteListener.java @@ -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); + } } } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java index 97bcf4c9014..09f35d9ec12 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java @@ -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 */ diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java index 5e3307746a2..672b6272501 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java @@ -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 generator; - - private GeneratingContentProvider(IntFunction 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 iterator() - { - return new Iterator() + @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 generator; + + private GeneratingContentProvider(IntFunction generator) + { + this.generator = generator; + } + + @Override + public long getLength() + { + return -1; + } + + @Override + public boolean isReproducible() + { + return true; + } + + @Override + public Iterator iterator() + { + return new Iterator() + { + 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; + } + }; + } + } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java index 9038ec52f95..f4eb3090a07 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java @@ -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,64 @@ 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.setMaxRedirects(-1); + client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .timeout(5, TimeUnit.SECONDS) + .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 +574,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 +606,6 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest // Echo content back IO.copy(request.getInputStream(), response.getOutputStream()); } - finally - { - baseRequest.setHandled(true); - } } } } diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java index b32c271ff45..a1483e769c6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java @@ -18,16 +18,6 @@ package org.eclipse.jetty.client; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -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.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.io.InputStream; import java.io.OutputStream; @@ -106,6 +96,16 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +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.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; + @ExtendWith(WorkDirExtension.class) public class HttpClientTest extends AbstractHttpClientServerTest { From 23da561fec8964e640883748e2162153942683fa Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Fri, 15 Mar 2019 09:48:49 +0100 Subject: [PATCH 03/74] Fixes #3411 - HttpClient does not timeout during multiple redirection. Updates after review. Removed special logic to test for same URI redirection, so it will fall back into the normal case where redirects are counted against a maximum. Signed-off-by: Simone Bordet --- .../org/eclipse/jetty/client/HttpRedirector.java | 13 ++----------- .../jetty/client/HttpClientRedirectTest.java | 10 +++------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java index 9bd9f208a88..47292818600 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.client; import java.net.URI; import java.net.URISyntaxException; import java.util.List; -import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -63,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); @@ -159,14 +158,6 @@ public class HttpRedirector URI newURI = extractRedirectURI(response); if (newURI != null) { - boolean absolute = newURI.isAbsolute(); - URI uri = request.getURI(); - if (absolute && newURI.equals(uri) || - !absolute && Objects.equals(newURI.getPath(), uri.getPath())) - { - fail(request, response, new HttpResponseException("Redirect to same URI: " + location, response)); - return null; - } if (LOG.isDebugEnabled()) LOG.debug("Redirecting to {} (Location: {})", newURI, location); return redirect(request, response, listener, newURI); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java index f4eb3090a07..8da2a30390b 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java @@ -483,13 +483,9 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest }); ExecutionException x = assertThrows(ExecutionException.class, () -> - { - client.setMaxRedirects(-1); - client.newRequest("localhost", connector.getLocalPort()) - .scheme(scenario.getScheme()) - .timeout(5, TimeUnit.SECONDS) - .send(); - }); + client.newRequest("localhost", connector.getLocalPort()) + .scheme(scenario.getScheme()) + .send()); assertThat(x.getCause(), Matchers.instanceOf(HttpResponseException.class)); } From b7e3d6ce5e0eb7b22c6bd162da38603b43ed0282 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 19 Mar 2019 16:40:45 +1100 Subject: [PATCH 04/74] Issue #3361 thread safe addHandler Removed synchronization for now, leaving just some cleanups Signed-off-by: Greg Wilkins --- .../handler/ContextHandlerCollection.java | 10 +--- .../server/handler/HandlerCollection.java | 60 +++++++------------ 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index f0b020808f0..19ea768f0f3 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -138,7 +138,6 @@ public class ContextHandlerCollection extends HandlerCollection } break loop; } - if (LOG.isDebugEnabled()) { @@ -155,12 +154,9 @@ public class ContextHandlerCollection extends HandlerCollection @Override public void setHandlers(Handler[] handlers) { - synchronized (this) - { - super.setHandlers(handlers); - if (isStarted()) - mapContexts(); - } + super.setHandlers(handlers); + if (isStarted()) + mapContexts(); } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index 1de7d942952..e32cc01cc3d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -86,28 +86,25 @@ public class HandlerCollection extends AbstractHandlerContainer */ public void setHandlers(Handler[] handlers) { - synchronized (this) + if (!_mutableWhenRunning && isStarted()) + throw new IllegalStateException(STARTED); + + if (handlers!=null) { - if (!_mutableWhenRunning && isStarted()) - throw new IllegalStateException(STARTED); - - if (handlers!=null) - { - // check for loops - for (Handler handler:handlers) - if (handler == this || (handler instanceof HandlerContainer && + // 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"); + throw new IllegalStateException("setHandler loop"); - // Set server - for (Handler handler:handlers) - if (handler.getServer()!=getServer()) - handler.setServer(getServer()); - } - Handler[] old=_handlers; - _handlers = handlers; - updateBeans(old, handlers); + // Set server + for (Handler handler:handlers) + if (handler.getServer()!=getServer()) + handler.setServer(getServer()); } + + updateBeans(_handlers,handlers); + _handlers = handlers; } /* ------------------------------------------------------------ */ @@ -161,10 +158,7 @@ public class HandlerCollection extends AbstractHandlerContainer */ public void addHandler(Handler handler) { - synchronized(this) - { - setHandlers(ArrayUtil.addToArray(getHandlers(), handler, Handler.class)); - } + setHandlers(ArrayUtil.addToArray(getHandlers(), handler, Handler.class)); } /* ------------------------------------------------------------ */ @@ -174,22 +168,16 @@ public class HandlerCollection extends AbstractHandlerContainer */ public void prependHandler(Handler handler) { - synchronized (this) - { - setHandlers(ArrayUtil.prependToArray(handler, getHandlers(), Handler.class)); - } + setHandlers(ArrayUtil.prependToArray(handler, getHandlers(), Handler.class)); } /* ------------------------------------------------------------ */ public void removeHandler(Handler handler) { - synchronized (this) - { - Handler[] handlers = getHandlers(); + Handler[] handlers = getHandlers(); - if (handlers!=null && handlers.length>0 ) - setHandlers(ArrayUtil.removeFromArray(handlers, handler)); - } + if (handlers!=null && handlers.length>0 ) + setHandlers(ArrayUtil.removeFromArray(handlers, handler)); } /* ------------------------------------------------------------ */ @@ -208,12 +196,8 @@ public class HandlerCollection extends AbstractHandlerContainer { if (!isStopped()) throw new IllegalStateException("!STOPPED"); - Handler[] children; - synchronized (this) - { - children = getChildHandlers(); - setHandlers(null); - } + Handler[] children = getChildHandlers(); + setHandlers(null); for (Handler child: children) child.destroy(); super.destroy(); From 49eadc52464c060da219fb989d934c5b5904068e Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 19 Mar 2019 17:58:27 +1100 Subject: [PATCH 05/74] Issue #3361 thread safe addHandler Made Context mapping atomic with a volatile mapping Signed-off-by: Greg Wilkins --- .../handler/ContextHandlerCollection.java | 84 +++++++++++++------ 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index 19ea768f0f3..4bbfaa1e111 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -24,8 +24,6 @@ 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; @@ -59,8 +57,7 @@ public class ContextHandlerCollection extends HandlerCollection { private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class); - private final ConcurrentMap _contextBranches = new ConcurrentHashMap<>(); - private volatile Trie> _pathBranches; + private volatile Mapping _mapping; private Class _contextClass = ContextHandler.class; /* ------------------------------------------------------------ */ @@ -83,32 +80,32 @@ public class ContextHandlerCollection extends HandlerCollection @ManagedOperation("update the mapping of context path to context") public void mapContexts() { - _contextBranches.clear(); - - Handler[] handlers = getHandlers(); + mapContexts(getHandlers()); + } + + private void mapContexts(Handler[] handlers) + { if (handlers==null) { - _pathBranches=new ArrayTernaryTrie<>(false,16); + _mapping = new Mapping(1); return; } // Create map of contextPath to handler Branch - Map map = new HashMap<>(); + // A branch is a Handler that could contain 0 or more ContextHandlers + Map 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 entry: map.entrySet()) + // Sort the branches for each contextPath so those with virtual hosts are considered before those without + for (Map.Entry entry: path2Branches.entrySet()) { Branch[] branches=entry.getValue(); Branch[] sorted=new Branch[branches.length]; @@ -124,13 +121,13 @@ public class ContextHandlerCollection extends HandlerCollection // Loop until we have a big enough trie to hold all the context paths int capacity=512; - Trie> trie; + Mapping mapping; loop: while(true) { - trie=new ArrayTernaryTrie<>(false,capacity); - for (Map.Entry entry: map.entrySet()) + mapping = new Mapping(capacity); + for (Map.Entry entry: path2Branches.entrySet()) { - if (!trie.put(entry.getKey().substring(1),entry)) + if (!mapping._pathBranches.put(entry.getKey().substring(1),entry)) { capacity+=512; continue loop; @@ -141,10 +138,22 @@ public class ContextHandlerCollection extends HandlerCollection 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()); + } + } + + // Update volatile mapping + _mapping = mapping; } /* ------------------------------------------------------------ */ @@ -156,7 +165,7 @@ public class ContextHandlerCollection extends HandlerCollection { super.setHandlers(handlers); if (isStarted()) - mapContexts(); + mapContexts(handlers); } /* ------------------------------------------------------------ */ @@ -167,6 +176,13 @@ public class ContextHandlerCollection extends HandlerCollection super.doStart(); } + /* ------------------------------------------------------------ */ + @Override + protected void doStop() throws Exception + { + super.doStop(); + _mapping = null; + } /* ------------------------------------------------------------ */ /* @@ -175,13 +191,17 @@ public class ContextHandlerCollection extends HandlerCollection @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + Mapping mapping = _mapping; + if (mapping==null) + return; + 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); @@ -193,7 +213,7 @@ public class ContextHandlerCollection extends HandlerCollection if (target.startsWith("/")) { - Trie> pathBranches = _pathBranches; + Trie> pathBranches = mapping._pathBranches; if (pathBranches==null) return; @@ -340,5 +360,17 @@ public class ContextHandlerCollection extends HandlerCollection } } + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + private static class Mapping + { + private final Map _contextBranches = new HashMap<>(); + private final Trie> _pathBranches; + Mapping(int capacity) + { + _pathBranches = new ArrayTernaryTrie(false, capacity); + } + } } From 79c1700f6248964c0abaee4389d4012ae805142b Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 19 Mar 2019 18:57:55 +1100 Subject: [PATCH 06/74] Issue #3361 thread safe addHandler Make handler list and context mappings controlled by a single CaS operation Signed-off-by: Greg Wilkins --- .../handler/ContextHandlerCollection.java | 71 +++++----------- .../server/handler/HandlerCollection.java | 84 +++++++++++++++---- 2 files changed, 91 insertions(+), 64 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index 4bbfaa1e111..f5dafc1aff1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -57,7 +57,6 @@ public class ContextHandlerCollection extends HandlerCollection { private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class); - private volatile Mapping _mapping; private Class _contextClass = ContextHandler.class; /* ------------------------------------------------------------ */ @@ -69,26 +68,25 @@ public class ContextHandlerCollection extends HandlerCollection /* ------------------------------------------------------------ */ public ContextHandlerCollection(ContextHandler... contexts) { - super(true,contexts); + super(true); + setHandlers(contexts); } - /* ------------------------------------------------------------ */ - /** - * Remap the context paths. - */ @ManagedOperation("update the mapping of context path to context") + @Deprecated public void mapContexts() { - mapContexts(getHandlers()); + LOG.warn("mapContexts is Deprecated"); } - private void mapContexts(Handler[] handlers) + /* ------------------------------------------------------------ */ + @Override + protected Handlers newHandlers(Handler[] handlers) { - if (handlers==null) + if (handlers==null || handlers.length==0) { - _mapping = new Mapping(1); - return; + return null; } // Create map of contextPath to handler Branch @@ -124,7 +122,7 @@ public class ContextHandlerCollection extends HandlerCollection Mapping mapping; loop: while(true) { - mapping = new Mapping(capacity); + mapping = new Mapping(handlers, capacity); for (Map.Entry entry: path2Branches.entrySet()) { if (!mapping._pathBranches.put(entry.getKey().substring(1),entry)) @@ -152,36 +150,7 @@ public class ContextHandlerCollection extends HandlerCollection } } - // Update volatile mapping - _mapping = 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(handlers); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - mapContexts(); - super.doStart(); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - _mapping = null; + return mapping; } /* ------------------------------------------------------------ */ @@ -191,7 +160,11 @@ public class ContextHandlerCollection extends HandlerCollection @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - Mapping mapping = _mapping; + Handlers handlers = _handlers.get(); + if (handlers==null) + return; + + Mapping mapping = (Mapping)handlers; if (mapping==null) return; @@ -243,12 +216,11 @@ public class ContextHandlerCollection extends HandlerCollection } else { - Handler[] handlers = getHandlers(); - if (handlers==null) + if (mapping._handlers==null) return; - for (int i=0;i _contextBranches = new HashMap<>(); private final Trie> _pathBranches; - Mapping(int capacity) + Mapping(Handler[] handlers, int capacity) { + super(handlers); _pathBranches = new ArrayTernaryTrie(false, capacity); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index e32cc01cc3d..0c950a30f19 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -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 = new AtomicReference<>(); /* ------------------------------------------------------------ */ public HandlerCollection() @@ -77,7 +78,8 @@ public class HandlerCollection extends AbstractHandlerContainer @ManagedAttribute(value="Wrapped handlers", readonly=true) public Handler[] getHandlers() { - return _handlers; + Handlers handlers = _handlers.get(); + return handlers==null ? null : handlers._handlers; } /* ------------------------------------------------------------ */ @@ -89,22 +91,41 @@ public class HandlerCollection extends AbstractHandlerContainer if (!_mutableWhenRunning && isStarted()) throw new IllegalStateException(STARTED); + while(!updateHandlers(_handlers.get(),newHandlers(handlers))); + } + + /* ------------------------------------------------------------ */ + 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) + 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) + for (Handler handler:handlers._handlers) if (handler.getServer()!=getServer()) handler.setServer(getServer()); } - updateBeans(_handlers,handlers); - _handlers = handlers; + + if (_handlers.compareAndSet(old,handlers)) + { + updateBeans(old==null?null:old._handlers,handlers==null?null:handlers._handlers); + return true; + } + return false; } /* ------------------------------------------------------------ */ @@ -114,17 +135,19 @@ public class HandlerCollection extends AbstractHandlerContainer { if (isStarted()) { - Handler[] handlers = _handlers; - if (handlers==null || handlers.length==0) + Handlers handlers = _handlers.get(); + if (handlers==null) return; + Handler[] h = handlers._handlers; + MultiException mex=null; - for (int i=0;i0 ) - setHandlers(ArrayUtil.removeFromArray(handlers, handler)); + if (old==null || old._handlers.length==0) + break; + Handlers handlers = newHandlers(ArrayUtil.removeFromArray(old._handlers, handler)); + if (updateHandlers(old,handlers)) + break; + } } /* ------------------------------------------------------------ */ @@ -202,4 +243,17 @@ public class HandlerCollection extends AbstractHandlerContainer child.destroy(); super.destroy(); } + + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + /* ------------------------------------------------------------ */ + protected static class Handlers + { + final Handler[] _handlers; + + protected Handlers(Handler[] handlers) + { + this._handlers = handlers; + } + } } From bfc5b1fac55ceb9e6a89730b779787e206893989 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 19 Mar 2019 17:36:39 +0100 Subject: [PATCH 07/74] Issue #3180 - Review client support for Unix sockets. Reviewed the implementation. Got rid of the single channel stored in the HttpClientTransport. Re-enabled tests on the Unix socket transport. Updated JNR to 0.22. Signed-off-by: Simone Bordet --- .../AbstractConnectorHttpClientTransport.java | 5 + .../config/etc/jetty-unixsocket-forwarded.xml | 3 +- .../main/config/etc/jetty-unixsocket-http.xml | 2 +- .../config/etc/jetty-unixsocket-http2c.xml | 3 - .../etc/jetty-unixsocket-proxy-protocol.xml | 4 +- .../config/etc/jetty-unixsocket-secure.xml | 3 +- .../src/main/config/etc/jetty-unixsocket.xml | 8 +- .../src/main/config/modules/unixsocket.mod | 8 +- .../jetty/unixsocket/UnixSocketConnector.java | 257 ++++++++---------- .../jetty/unixsocket/UnixSocketEndPoint.java | 15 +- .../HttpClientTransportOverUnixSockets.java | 65 ++--- .../org/eclipse/jetty/unixsocket/JnrTest.java | 101 +++---- .../jetty/unixsocket/UnixSocketClient.java | 26 +- .../unixsocket/UnixSocketProxyServer.java | 32 +-- .../jetty/unixsocket/UnixSocketServer.java | 33 +-- .../jetty/unixsocket/UnixSocketTest.java | 107 ++++---- pom.xml | 2 +- .../jetty/http/client/AsyncIOServletTest.java | 37 +-- .../jetty/http/client/HttpClientLoadTest.java | 30 +- .../jetty/http/client/HttpClientTest.java | 20 +- .../client/RoundRobinConnectionPoolTest.java | 14 +- .../jetty/http/client/ServerTimeoutsTest.java | 25 +- .../jetty/http/client/TransportProvider.java | 17 +- .../jetty/http/client/TransportScenario.java | 58 ++-- 24 files changed, 375 insertions(+), 500 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java index 67f57a11486..81e57c4cd1b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java @@ -148,6 +148,11 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC return new ClientSelectorManager(client, getSelectors()); } + protected SelectorManager getSelectorManager() + { + return selectorManager; + } + protected class ClientSelectorManager extends SelectorManager { private final HttpClient client; diff --git a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-forwarded.xml b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-forwarded.xml index d30ea10a51c..f096db547cb 100644 --- a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-forwarded.xml +++ b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-forwarded.xml @@ -1,5 +1,6 @@ - + + diff --git a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http.xml b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http.xml index 0520c345b3d..ed7a3e23dca 100644 --- a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http.xml +++ b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http.xml @@ -1,4 +1,4 @@ - + diff --git a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http2c.xml b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http2c.xml index 40494fd5c79..a8ff7f92f3c 100644 --- a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http2c.xml +++ b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-http2c.xml @@ -1,9 +1,6 @@ - - - diff --git a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-proxy-protocol.xml b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-proxy-protocol.xml index 066a5086456..e21f7fdfc38 100644 --- a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-proxy-protocol.xml +++ b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-proxy-protocol.xml @@ -1,7 +1,7 @@ - + - + diff --git a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-secure.xml b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-secure.xml index 2a053233ccc..03a1467800b 100644 --- a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-secure.xml +++ b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket-secure.xml @@ -1,5 +1,6 @@ - + + diff --git a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket.xml b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket.xml index ecf1f43bb63..55bc73e581b 100644 --- a/jetty-unixsocket/src/main/config/etc/jetty-unixsocket.xml +++ b/jetty-unixsocket/src/main/config/etc/jetty-unixsocket.xml @@ -1,4 +1,4 @@ - + @@ -11,11 +11,7 @@ - - - - - + diff --git a/jetty-unixsocket/src/main/config/modules/unixsocket.mod b/jetty-unixsocket/src/main/config/modules/unixsocket.mod index 84a45d21831..a66fbdf9f6d 100644 --- a/jetty-unixsocket/src/main/config/modules/unixsocket.mod +++ b/jetty-unixsocket/src/main/config/modules/unixsocket.mod @@ -38,7 +38,7 @@ lib/jetty-unixsocket-${jetty.version}.jar lib/jnr/*.jar [license] -Jetty UnixSockets is implmented using the Java Native Runtime, which is an +Jetty UnixSockets is implemented using the Java Native Runtime, which is an open source project hosted on Github and released under the Apache 2.0 license. https://github.com/jnr/jnr-unixsocket http://www.apache.org/licenses/LICENSE-2.0.html @@ -46,13 +46,13 @@ http://www.apache.org/licenses/LICENSE-2.0.html [ini-template] ### Unix SocketHTTP Connector Configuration -## Connector host/address to bind to -# jetty.unixsocket=/tmp/jetty.sock +## Unix socket path to bind to +# jetty.unixsocket.path=/tmp/jetty.sock ## Connector idle timeout in milliseconds # jetty.unixsocket.idleTimeout=30000 -## Number of selectors (-1 picks default 1) +## Number of selectors (-1 picks default) # jetty.unixsocket.selectors=-1 ## ServerSocketChannel backlog (0 picks platform default) diff --git a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketConnector.java b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketConnector.java index 7767e772097..51ea5f46053 100644 --- a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketConnector.java +++ b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketConnector.java @@ -28,8 +28,11 @@ import java.nio.channels.Selector; import java.nio.file.Files; import java.nio.file.Paths; import java.util.concurrent.Executor; -import java.util.concurrent.Future; +import jnr.enxio.channels.NativeSelectorProvider; +import jnr.unixsocket.UnixServerSocketChannel; +import jnr.unixsocket.UnixSocketAddress; +import jnr.unixsocket.UnixSocketChannel; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.EndPoint; @@ -49,164 +52,129 @@ import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.Scheduler; -import jnr.enxio.channels.NativeSelectorProvider; -import jnr.unixsocket.UnixServerSocketChannel; -import jnr.unixsocket.UnixSocketAddress; -import jnr.unixsocket.UnixSocketChannel; - /** - * + *

A server-side connector for UNIX sockets.

*/ @ManagedObject("Connector using UNIX Socket") public class UnixSocketConnector extends AbstractConnector { + // See SockAddrUnix.ADDR_LENGTH. + public static final int MAX_UNIX_SOCKET_PATH_LENGTH = 107; private static final Logger LOG = Log.getLogger(UnixSocketConnector.class); - + private final SelectorManager _manager; private String _unixSocket = "/tmp/jetty.sock"; private volatile UnixServerSocketChannel _acceptChannel; private volatile int _acceptQueueSize = 0; private volatile boolean _reuseAddress = true; - - /* ------------------------------------------------------------ */ - /** HTTP Server Connection. - *

Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.

- * @param server The {@link Server} this connector will accept connection for. + /** + *

Constructs a UnixSocketConnector with the default configuration.

+ * + * @param server the {@link Server} this connector will accept connections for. */ - public UnixSocketConnector( @Name("server") Server server) + public UnixSocketConnector(@Name("server") Server server) { - this(server,null,null,null,-1,new HttpConnectionFactory()); - } - - /* ------------------------------------------------------------ */ - /** HTTP Server Connection. - *

Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.

- * @param server The {@link Server} this connector will accept connection for. - * @param selectors - * the number of selector threads, or <=0 for a default value. Selectors notice and schedule established connection that can make IO progress. - */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("selectors") int selectors) - { - this(server,null,null,null,selectors,new HttpConnectionFactory()); - } - - /* ------------------------------------------------------------ */ - /** HTTP Server Connection. - *

Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.

- * @param server The {@link Server} this connector will accept connection for. - * @param selectors - * the number of selector threads, or <=0 for a default value. Selectors notice and schedule established connection that can make IO progress. - * @param factories Zero or more {@link ConnectionFactory} instances used to create and configure connections. - */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("selectors") int selectors, - @Name("factories") ConnectionFactory... factories) - { - this(server,null,null,null,selectors,factories); + this(server, -1); } - /* ------------------------------------------------------------ */ - /** Generic Server Connection with default configuration. - *

Construct a Server Connector with the passed Connection factories.

- * @param server The {@link Server} this connector will accept connection for. - * @param factories Zero or more {@link ConnectionFactory} instances used to create and configure connections. + /** + *

Constructs a UnixSocketConnector with the given number of selectors

+ * + * @param server the {@link Server} this connector will accept connections for. + * @param selectors the number of selectors, or <=0 for a default value. */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("factories") ConnectionFactory... factories) + public UnixSocketConnector(@Name("server") Server server, @Name("selectors") int selectors) { - this(server,null,null,null,-1,factories); + this(server, selectors, new HttpConnectionFactory()); } - /* ------------------------------------------------------------ */ - /** HTTP Server Connection. - *

Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the primary protocol

. - * @param server The {@link Server} this connector will accept connection for. - * @param sslContextFactory If non null, then a {@link SslConnectionFactory} is instantiated and prepended to the - * list of HTTP Connection Factory. + /** + *

Constructs a UnixSocketConnector with the given ConnectionFactories.

+ * + * @param server the {@link Server} this connector will accept connections for. + * @param factories zero or more {@link ConnectionFactory} instances used to create and configure connections. */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("sslContextFactory") SslContextFactory sslContextFactory) + public UnixSocketConnector(@Name("server") Server server, @Name("factories") ConnectionFactory... factories) { - this(server,null,null,null,-1,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory())); + this(server, -1, factories); } - /* ------------------------------------------------------------ */ - /** HTTP Server Connection. - *

Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the primary protocol

. - * @param server The {@link Server} this connector will accept connection for. - * @param sslContextFactory If non null, then a {@link SslConnectionFactory} is instantiated and prepended to the - * list of HTTP Connection Factory. - * @param selectors - * the number of selector threads, or <=0 for a default value. Selectors notice and schedule established connection that can make IO progress. + /** + *

Constructs a UnixSocketConnector with the given selectors and ConnectionFactories.

+ * + * @param server the {@link Server} this connector will accept connections for. + * @param selectors the number of selectors, or <=0 for a default value. + * @param factories zero or more {@link ConnectionFactory} instances used to create and configure connections. */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("selectors") int selectors, - @Name("sslContextFactory") SslContextFactory sslContextFactory) + public UnixSocketConnector(@Name("server") Server server, @Name("selectors") int selectors, @Name("factories") ConnectionFactory... factories) { - this(server,null,null,null,selectors,AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory())); + this(server, null, null, null, selectors, factories); } - /* ------------------------------------------------------------ */ - /** Generic SSL Server Connection. - * @param server The {@link Server} this connector will accept connection for. - * @param sslContextFactory If non null, then a {@link SslConnectionFactory} is instantiated and prepended to the - * list of ConnectionFactories, with the first factory being the default protocol for the SslConnectionFactory. - * @param factories Zero or more {@link ConnectionFactory} instances used to create and configure connections. + /** + *

Constructs a UnixSocketConnector with the given SslContextFactory.

+ * + * @param server the {@link Server} this connector will accept connections for. + * @param sslContextFactory when non null a {@link SslConnectionFactory} prepended to the other ConnectionFactories */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("sslContextFactory") SslContextFactory sslContextFactory, - @Name("factories") ConnectionFactory... factories) + public UnixSocketConnector(@Name("server") Server server, @Name("sslContextFactory") SslContextFactory sslContextFactory) + { + this(server, -1, sslContextFactory); + } + + /** + *

Constructs a UnixSocketConnector with the given selectors and SslContextFactory.

. + * + * @param server the {@link Server} this connector will accept connections for. + * @param sslContextFactory when non null a {@link SslConnectionFactory} prepended to the other ConnectionFactories + * @param selectors the number of selectors, or <=0 for a default value. + */ + public UnixSocketConnector(@Name("server") Server server, @Name("selectors") int selectors, @Name("sslContextFactory") SslContextFactory sslContextFactory) + { + this(server, null, null, null, selectors, AbstractConnectionFactory.getFactories(sslContextFactory, new HttpConnectionFactory())); + } + + /** + *

Constructs a UnixSocketConnector with the given SslContextFactory and ConnectionFactories.

. + * + * @param server the {@link Server} this connector will accept connections for. + * @param sslContextFactory when non null a {@link SslConnectionFactory} prepended to the other ConnectionFactories + * @param factories zero or more {@link ConnectionFactory} instances used to create and configure connections. + */ + public UnixSocketConnector(@Name("server") Server server, @Name("sslContextFactory") SslContextFactory sslContextFactory, @Name("factories") ConnectionFactory... factories) { this(server, null, null, null, -1, AbstractConnectionFactory.getFactories(sslContextFactory, factories)); } - /** Generic Server Connection. - * @param server - * The server this connector will be accept connection for. - * @param executor - * An executor used to run tasks for handling requests, acceptors and selectors. - * If null then use the servers executor - * @param scheduler - * A scheduler used to schedule timeouts. If null then use the servers scheduler - * @param bufferPool - * A ByteBuffer pool used to allocate buffers. If null then create a private pool with default configuration. - * @param selectors - * the number of selector threads, or <=0 for a default value(1). Selectors notice and schedule established connection that can make IO progress. - * @param factories - * Zero or more {@link ConnectionFactory} instances used to create and configure connections. + /** + *

Constructs a UnixSocketConnector with the given parameters.

. + * + * @param server the {@link Server} this connector will accept connections for. + * @param executor the executor that runs tasks for handling requests, acceptors and selectors. + * @param scheduler the scheduler used to schedule timed tasks. + * @param bufferPool the ByteBufferPool used to allocate buffers. + * @param selectors the number of selectors, or <=0 for a default value. + * @param factories zero or more {@link ConnectionFactory} instances used to create and configure connections. */ - public UnixSocketConnector( - @Name("server") Server server, - @Name("executor") Executor executor, - @Name("scheduler") Scheduler scheduler, - @Name("bufferPool") ByteBufferPool bufferPool, - @Name("selectors") int selectors, - @Name("factories") ConnectionFactory... factories) + public UnixSocketConnector(@Name("server") Server server, @Name("executor") Executor executor, @Name("scheduler") Scheduler scheduler, @Name("bufferPool") ByteBufferPool bufferPool, @Name("selectors") int selectors, @Name("factories") ConnectionFactory... factories) { - super(server,executor,scheduler,bufferPool,0,factories); - _manager = newSelectorManager(getExecutor(), getScheduler(), - selectors>0?selectors:1); + super(server, executor, scheduler, bufferPool, 0, factories); + _manager = newSelectorManager(getExecutor(), getScheduler(), selectors > 0 ? selectors : 1); addBean(_manager, true); - setAcceptorPriorityDelta(-2); } - @ManagedAttribute + @ManagedAttribute("The UNIX socket file name") public String getUnixSocket() { return _unixSocket; } - + public void setUnixSocket(String filename) { - _unixSocket=filename; + if (filename.length() > MAX_UNIX_SOCKET_PATH_LENGTH) + throw new IllegalArgumentException("Unix socket path too long"); + _unixSocket = filename; } protected SelectorManager newSelectorManager(Executor executor, Scheduler scheduler, int selectors) @@ -219,11 +187,10 @@ public class UnixSocketConnector extends AbstractConnector { open(); super.doStart(); - - if (getAcceptors()==0) + if (getAcceptors() == 0) _manager.acceptor(_acceptChannel); } - + @Override protected void doStop() throws Exception { @@ -234,10 +201,9 @@ public class UnixSocketConnector extends AbstractConnector public boolean isOpen() { UnixServerSocketChannel channel = _acceptChannel; - return channel!=null && channel.isOpen(); + return channel != null && channel.isOpen(); } - public void open() throws IOException { if (_acceptChannel == null) @@ -246,8 +212,7 @@ public class UnixSocketConnector extends AbstractConnector file.deleteOnExit(); SocketAddress bindAddress = new UnixSocketAddress(file); UnixServerSocketChannel serverChannel = UnixServerSocketChannel.open(); - - serverChannel.configureBlocking(getAcceptors()>0); + serverChannel.configureBlocking(getAcceptors() > 0); try { serverChannel.socket().bind(bindAddress, getAcceptQueueSize()); @@ -259,18 +224,11 @@ public class UnixSocketConnector extends AbstractConnector } addBean(serverChannel); if (LOG.isDebugEnabled()) - LOG.debug("opened {}",serverChannel); + LOG.debug("opened {}", serverChannel); _acceptChannel = serverChannel; } } - @Override - public Future shutdown() - { - // shutdown all the connections - return super.shutdown(); - } - public void close() { UnixServerSocketChannel serverChannel = _acceptChannel; @@ -297,7 +255,7 @@ public class UnixSocketConnector extends AbstractConnector { Files.deleteIfExists(Paths.get(_unixSocket)); } - catch ( IOException e ) + catch (IOException e) { LOG.warn(e); } @@ -311,16 +269,16 @@ public class UnixSocketConnector extends AbstractConnector UnixServerSocketChannel serverChannel = _acceptChannel; if (serverChannel != null && serverChannel.isOpen()) { - LOG.debug("accept {}",serverChannel); + LOG.debug("accept {}", serverChannel); UnixSocketChannel channel = serverChannel.accept(); - LOG.debug("accepted {}",channel); + LOG.debug("accepted {}", channel); accepted(channel); } } - + protected void accepted(UnixSocketChannel channel) throws IOException { - channel.configureBlocking(false); + channel.configureBlocking(false); _manager.accept(channel); } @@ -335,12 +293,11 @@ public class UnixSocketConnector extends AbstractConnector return _acceptChannel; } - protected UnixSocketEndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException + protected UnixSocketEndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) { - return new UnixSocketEndPoint((UnixSocketChannel)channel,selector,key,getScheduler()); + return new UnixSocketEndPoint((UnixSocketChannel)channel, selector, key, getScheduler()); } - /** * @return the accept queue size */ @@ -362,6 +319,7 @@ public class UnixSocketConnector extends AbstractConnector * @return whether the server socket reuses addresses * @see ServerSocket#getReuseAddress() */ + @ManagedAttribute("Whether the server socket reuses addresses") public boolean getReuseAddress() { return _reuseAddress; @@ -376,15 +334,12 @@ public class UnixSocketConnector extends AbstractConnector _reuseAddress = reuseAddress; } - @Override public String toString() { - return String.format("%s{%s}", - super.toString(), - _unixSocket); + return String.format("%s{%s}", super.toString(), _unixSocket); } - + protected class UnixSocketConnectorManager extends SelectorManager { public UnixSocketConnectorManager(Executor executor, Scheduler scheduler, int selectors) @@ -403,17 +358,17 @@ public class UnixSocketConnector extends AbstractConnector { return NativeSelectorProvider.getInstance().openSelector(); } - + @Override - protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) throws IOException + protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) { - UnixSocketEndPoint endp = UnixSocketConnector.this.newEndPoint(channel, selector, selectionKey); - endp.setIdleTimeout(getIdleTimeout()); - return endp; + UnixSocketEndPoint endPoint = UnixSocketConnector.this.newEndPoint(channel, selector, selectionKey); + endPoint.setIdleTimeout(getIdleTimeout()); + return endPoint; } @Override - public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException + public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) { return getDefaultConnectionFactory().newConnection(UnixSocketConnector.this, endpoint); } @@ -448,10 +403,10 @@ public class UnixSocketConnector extends AbstractConnector protected SelectableChannel doAccept(SelectableChannel server) throws IOException { if (LOG.isDebugEnabled()) - LOG.debug("doAccept async {}",server); + LOG.debug("doAccept async {}", server); UnixSocketChannel channel = ((UnixServerSocketChannel)server).accept(); if (LOG.isDebugEnabled()) - LOG.debug("accepted async {}",channel); + LOG.debug("accepted async {}", channel); return channel; } } diff --git a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java index 3556b73c390..57af91a5110 100644 --- a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java +++ b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/UnixSocketEndPoint.java @@ -20,31 +20,25 @@ package org.eclipse.jetty.unixsocket; import java.io.IOException; import java.net.InetSocketAddress; -import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; +import jnr.unixsocket.UnixSocketChannel; import org.eclipse.jetty.io.ChannelEndPoint; -import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.io.ManagedSelector; -import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.thread.Scheduler; -import jnr.unixsocket.UnixSocketChannel; - public class UnixSocketEndPoint extends ChannelEndPoint { private static final Logger LOG = Log.getLogger(UnixSocketEndPoint.class); - private static final Logger CEPLOG = Log.getLogger(ChannelEndPoint.class); - private final UnixSocketChannel _channel; - + public UnixSocketEndPoint(UnixSocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler) { - super(channel,selector,key,scheduler); - _channel=channel; + super(channel, selector, key, scheduler); + _channel = channel; } @Override @@ -59,7 +53,6 @@ public class UnixSocketEndPoint extends ChannelEndPoint return null; } - @Override protected void doShutdownOutput() { diff --git a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java index 9e30713099a..989a3ed8b21 100644 --- a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java +++ b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java @@ -25,71 +25,60 @@ import java.net.SocketException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.Map; +import jnr.enxio.channels.NativeSelectorProvider; +import jnr.unixsocket.UnixSocketAddress; +import jnr.unixsocket.UnixSocketChannel; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ManagedSelector; import org.eclipse.jetty.io.SelectorManager; -import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; import org.eclipse.jetty.unixsocket.UnixSocketEndPoint; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; -import jnr.enxio.channels.NativeSelectorProvider; -import jnr.unixsocket.UnixSocketAddress; -import jnr.unixsocket.UnixSocketChannel; - -public class HttpClientTransportOverUnixSockets - extends HttpClientTransportOverHTTP +public class HttpClientTransportOverUnixSockets extends HttpClientTransportOverHTTP { - private static final Logger LOG = Log.getLogger( HttpClientTransportOverUnixSockets.class ); - + private static final Logger LOG = Log.getLogger(HttpClientTransportOverUnixSockets.class); + private String _unixSocket; - private SelectorManager selectorManager; - private UnixSocketChannel channel; - - public HttpClientTransportOverUnixSockets( String unixSocket ) + public HttpClientTransportOverUnixSockets(String unixSocket) { - if ( unixSocket == null ) - { - throw new IllegalArgumentException( "Unix socket file cannot be null" ); - } + if (unixSocket == null) + throw new IllegalArgumentException("Unix socket file cannot be null"); this._unixSocket = unixSocket; } @Override protected SelectorManager newSelectorManager(HttpClient client) { - return selectorManager = new UnixSocketSelectorManager(client,getSelectors()); + return new UnixSocketSelectorManager(client, getSelectors()); } @Override - public void connect( InetSocketAddress address, Map context ) + public void connect(InetSocketAddress address, Map context) { - + UnixSocketChannel channel = null; try { InetAddress inet = address.getAddress(); if (!inet.isLoopbackAddress() && !inet.isLinkLocalAddress() && !inet.isSiteLocalAddress()) - throw new IOException("UnixSocket cannot connect to "+address.getHostString()); - - // Open a unix socket - UnixSocketAddress unixAddress = new UnixSocketAddress( this._unixSocket ); - channel = UnixSocketChannel.open( unixAddress ); - + throw new IOException("UnixSocket cannot connect to " + address.getHostString()); + + UnixSocketAddress unixAddress = new UnixSocketAddress(_unixSocket); + channel = UnixSocketChannel.open(unixAddress); + HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY); HttpClient client = destination.getHttpClient(); configure(client, channel); channel.configureBlocking(false); - selectorManager.accept(channel, context); + getSelectorManager().accept(channel, context); } // Must catch all exceptions, since some like // UnresolvedAddressException are not IOExceptions. @@ -120,7 +109,7 @@ public class HttpClientTransportOverUnixSockets { protected UnixSocketSelectorManager(HttpClient client, int selectors) { - super(client,selectors); + super(client, selectors); } @Override @@ -137,20 +126,4 @@ public class HttpClientTransportOverUnixSockets return endp; } } - - @Override - protected void doStop() - throws Exception - { - super.doStop(); - try - { - if (channel != null) - channel.close(); - } - catch (IOException xx) - { - LOG.ignore(xx); - } - } } diff --git a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/JnrTest.java b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/JnrTest.java index ecff07eb60f..7a2932e7ba7 100644 --- a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/JnrTest.java +++ b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/JnrTest.java @@ -36,130 +36,119 @@ public class JnrTest java.io.File path = new java.io.File("/tmp/fubar.sock"); path.deleteOnExit(); UnixSocketAddress address = new UnixSocketAddress(path); - - + UnixServerSocketChannel serverChannel = UnixServerSocketChannel.open(); Selector serverSelector = NativeSelectorProvider.getInstance().openSelector(); serverChannel.configureBlocking(false); serverChannel.socket().bind(address); serverChannel.register(serverSelector, SelectionKey.OP_ACCEPT, "SERVER"); - System.err.printf("serverChannel=%s,%n",serverChannel); - - UnixSocketChannel client = UnixSocketChannel.open( address ); + System.err.printf("serverChannel=%s,%n", serverChannel); + + UnixSocketChannel client = UnixSocketChannel.open(address); Selector clientSelector = NativeSelectorProvider.getInstance().openSelector(); client.configureBlocking(false); - SelectionKey clientKey = client.register(clientSelector,0,"client"); - - System.err.printf("client=%s connected=%b pending=%b%n",client,client.isConnected(),client.isConnectionPending()); + SelectionKey clientKey = client.register(clientSelector, 0, "client"); + + System.err.printf("client=%s connected=%b pending=%b%n", client, client.isConnected(), client.isConnectionPending()); int selected = serverSelector.select(); - System.err.printf("serverSelected=%d %s%n",selected,serverSelector.selectedKeys()); - + System.err.printf("serverSelected=%d %s%n", selected, serverSelector.selectedKeys()); + SelectionKey key = serverSelector.selectedKeys().iterator().next(); serverSelector.selectedKeys().clear(); - System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b%n",key,key.attachment(),key.isConnectable(),key.isAcceptable(),key.isReadable(),key.isWritable()); + System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b%n", key, key.attachment(), key.isConnectable(), key.isAcceptable(), key.isReadable(), key.isWritable()); UnixSocketChannel server = serverChannel.accept(); server.configureBlocking(false); SelectionKey serverKey = server.register(serverSelector, SelectionKey.OP_READ, "server"); - System.err.printf("server=%s connected=%b pending=%b%n",server,server.isConnected(),server.isConnectionPending()); - + System.err.printf("server=%s key=%s connected=%b pending=%b%n", server, serverKey, server.isConnected(), server.isConnectionPending()); + selected = serverSelector.selectNow(); - System.err.printf("serverSelected=%d %s%n",selected,serverSelector.selectedKeys()); - + System.err.printf("serverSelected=%d %s%n", selected, serverSelector.selectedKeys()); + ByteBuffer buffer = ByteBuffer.allocate(32768); buffer.clear(); int read = server.read(buffer); buffer.flip(); - System.err.printf("server read=%d%n",read); + System.err.printf("server read=%d%n", read); - selected = clientSelector.selectNow(); - System.err.printf("clientSelected=%d %s%n",selected,clientSelector.selectedKeys()); - + System.err.printf("clientSelected=%d %s%n", selected, clientSelector.selectedKeys()); + int wrote = client.write(ByteBuffer.wrap("Hello".getBytes(StandardCharsets.ISO_8859_1))); - System.err.printf("client wrote=%d%n",wrote); - + System.err.printf("client wrote=%d%n", wrote); + selected = serverSelector.selectNow(); - System.err.printf("serverSelected=%d %s%n",selected,serverSelector.selectedKeys()); + System.err.printf("serverSelected=%d %s%n", selected, serverSelector.selectedKeys()); key = serverSelector.selectedKeys().iterator().next(); serverSelector.selectedKeys().clear(); - System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b ch=%s%n",key,key.attachment(),key.isConnectable(),key.isAcceptable(),key.isReadable(),key.isWritable(),key.channel()); + System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b ch=%s%n", key, key.attachment(), key.isConnectable(), key.isAcceptable(), key.isReadable(), key.isWritable(), key.channel()); buffer.clear(); read = server.read(buffer); buffer.flip(); - System.err.printf("server read=%d '%s'%n",read,new String(buffer.array(),0,buffer.limit(),StandardCharsets.ISO_8859_1)); + System.err.printf("server read=%d '%s'%n", read, new String(buffer.array(), 0, buffer.limit(), StandardCharsets.ISO_8859_1)); - - selected = clientSelector.selectNow(); - System.err.printf("clientSelected=%d %s%n",selected,clientSelector.selectedKeys()); + System.err.printf("clientSelected=%d %s%n", selected, clientSelector.selectedKeys()); wrote = server.write(ByteBuffer.wrap("Ciao!".getBytes(StandardCharsets.ISO_8859_1))); - System.err.printf("server wrote=%d%n",wrote); - + System.err.printf("server wrote=%d%n", wrote); + selected = clientSelector.selectNow(); - System.err.printf("clientSelected=%d %s%n",selected,clientSelector.selectedKeys()); - + System.err.printf("clientSelected=%d %s%n", selected, clientSelector.selectedKeys()); + clientKey.interestOps(SelectionKey.OP_READ); - + selected = clientSelector.selectNow(); - System.err.printf("clientSelected=%d %s%n",selected,clientSelector.selectedKeys()); + System.err.printf("clientSelected=%d %s%n", selected, clientSelector.selectedKeys()); key = clientSelector.selectedKeys().iterator().next(); clientSelector.selectedKeys().clear(); - System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b ch=%s%n",key,key.attachment(),key.isConnectable(),key.isAcceptable(),key.isReadable(),key.isWritable(),key.channel()); + System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b ch=%s%n", key, key.attachment(), key.isConnectable(), key.isAcceptable(), key.isReadable(), key.isWritable(), key.channel()); buffer.clear(); read = client.read(buffer); buffer.flip(); - System.err.printf("client read=%d '%s'%n",read,new String(buffer.array(),0,buffer.limit(),StandardCharsets.ISO_8859_1)); + System.err.printf("client read=%d '%s'%n", read, new String(buffer.array(), 0, buffer.limit(), StandardCharsets.ISO_8859_1)); - System.err.println("So far so good.... now it gets strange..."); - - + // Let's write until flow control hit int size = buffer.capacity(); - Arrays.fill(buffer.array(),0,size,(byte)'X'); + Arrays.fill(buffer.array(), 0, size, (byte)'X'); long written = 0; - while(true) + while (true) { buffer.position(0).limit(size); wrote = server.write(buffer); - - System.err.printf("server wrote %d/%d remaining=%d%n",wrote,size,buffer.remaining()); - - if (buffer.remaining()!=(size-wrote)) + + System.err.printf("server wrote %d/%d remaining=%d%n", wrote, size, buffer.remaining()); + + if (buffer.remaining() != (size - wrote)) System.err.printf("BUG!!!!!!!!!!!!!!!!%n"); - - if (wrote==0) + + if (wrote == 0) break; - written+=wrote; + written += wrote; } - System.err.printf("server wrote %d before flow control%n",written); - - + System.err.printf("server wrote %d before flow control%n", written); selected = clientSelector.selectNow(); - System.err.printf("clientSelected=%d %s%n",selected,clientSelector.selectedKeys()); + System.err.printf("clientSelected=%d %s%n", selected, clientSelector.selectedKeys()); key = clientSelector.selectedKeys().iterator().next(); clientSelector.selectedKeys().clear(); - System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b ch=%s%n",key,key.attachment(),key.isConnectable(),key.isAcceptable(),key.isReadable(),key.isWritable(),key.channel()); + System.err.printf("key=%s/%s c=%b a=%b r=%b w=%b ch=%s%n", key, key.attachment(), key.isConnectable(), key.isAcceptable(), key.isReadable(), key.isWritable(), key.channel()); buffer.clear(); buffer.limit(32); read = client.read(buffer); buffer.flip(); - System.err.printf("client read=%d '%s'%n",read,new String(buffer.array(),0,buffer.limit(),StandardCharsets.ISO_8859_1)); - + System.err.printf("client read=%d '%s'%n", read, new String(buffer.array(), 0, buffer.limit(), StandardCharsets.ISO_8859_1)); server.close(); client.close(); - } - } diff --git a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketClient.java b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketClient.java index 66ae618df6d..00238f2c59e 100644 --- a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketClient.java +++ b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketClient.java @@ -24,12 +24,10 @@ import java.io.PrintWriter; import java.nio.CharBuffer; import java.nio.channels.Channels; import java.nio.charset.StandardCharsets; -import java.util.Date; - -import org.eclipse.jetty.toolchain.test.IO; import jnr.unixsocket.UnixSocketAddress; import jnr.unixsocket.UnixSocketChannel; +import org.eclipse.jetty.toolchain.test.IO; public class UnixSocketClient { @@ -37,7 +35,7 @@ public class UnixSocketClient { java.io.File path = new java.io.File("/tmp/jetty.sock"); java.io.File content = new java.io.File("/tmp/data.txt"); - + String method = "GET"; int content_length = 0; String body = null; @@ -47,12 +45,12 @@ public class UnixSocketClient body = IO.readToString(content); content_length = body.length(); } - String data = method+" / HTTP/1.1\r\n" - + "Host: unixsock\r\n" - + "Content-Length: "+content_length+"\r\n" - + "Connection: close\r\n" - + "\r\n"; - if (body!=null) + String data = method + " / HTTP/1.1\r\n" + + "Host: unixsock\r\n" + + "Content-Length: " + content_length + "\r\n" + + "Connection: close\r\n" + + "\r\n"; + if (body != null) data += body; while (true) @@ -61,18 +59,18 @@ public class UnixSocketClient UnixSocketChannel channel = UnixSocketChannel.open(address); System.out.println("connected to " + channel.getRemoteSocketAddress()); - PrintWriter w = new PrintWriter(new OutputStreamWriter(Channels.newOutputStream(channel),StandardCharsets.ISO_8859_1)); + PrintWriter w = new PrintWriter(new OutputStreamWriter(Channels.newOutputStream(channel), StandardCharsets.ISO_8859_1)); InputStreamReader r = new InputStreamReader(Channels.newInputStream(channel)); w.print(data); w.flush(); CharBuffer result = CharBuffer.allocate(4096); - String total=""; + String total = ""; int l = 0; - while (l>=0) + while (l >= 0) { - if (l>0) + if (l > 0) { result.flip(); total += result.toString(); diff --git a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketProxyServer.java b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketProxyServer.java index ce88a7acf2f..177e4285f58 100644 --- a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketProxyServer.java +++ b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketProxyServer.java @@ -25,7 +25,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Date; -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -37,32 +36,31 @@ import org.eclipse.jetty.server.handler.AbstractHandler; public class UnixSocketProxyServer { - public static void main (String... args) throws Exception + public static void main(String... args) throws Exception { Server server = new Server(); - + HttpConnectionFactory http = new HttpConnectionFactory(); ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol()); - UnixSocketConnector connector = new UnixSocketConnector(server,proxy,http); + UnixSocketConnector connector = new UnixSocketConnector(server, proxy, http); server.addConnector(connector); - + Path socket = Paths.get(connector.getUnixSocket()); if (Files.exists(socket)) Files.delete(socket); - + 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 { int l = 0; - if (request.getContentLength()!=0) + if (request.getContentLength() != 0) { InputStream in = request.getInputStream(); byte[] buffer = new byte[4096]; int r = 0; - while (r>=0) + while (r >= 0) { l += r; r = in.read(buffer); @@ -70,21 +68,21 @@ public class UnixSocketProxyServer } baseRequest.setHandled(true); response.setStatus(200); - response.getWriter().write("Hello World "+new Date() + "\r\n"); - response.getWriter().write("remote="+request.getRemoteAddr()+":"+request.getRemotePort()+"\r\n"); - response.getWriter().write("local ="+request.getLocalAddr()+":"+request.getLocalPort()+"\r\n"); - response.getWriter().write("read ="+l+"\r\n"); + response.getWriter().write("Hello World " + new Date() + "\r\n"); + response.getWriter().write("remote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\r\n"); + response.getWriter().write("local =" + request.getLocalAddr() + ":" + request.getLocalPort() + "\r\n"); + response.getWriter().write("read =" + l + "\r\n"); } }); - + server.start(); - + while (true) { Thread.sleep(5000); connector.dumpStdErr(); } - + // server.join(); } } diff --git a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketServer.java b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketServer.java index 4323fa8767e..147fde79183 100644 --- a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketServer.java +++ b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketServer.java @@ -25,43 +25,40 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Date; -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.ProxyConnectionFactory; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; public class UnixSocketServer { - public static void main (String... args) throws Exception + public static void main(String... args) throws Exception { Server server = new Server(); - + HttpConnectionFactory http = new HttpConnectionFactory(); - UnixSocketConnector connector = new UnixSocketConnector(server,http); + UnixSocketConnector connector = new UnixSocketConnector(server, http); server.addConnector(connector); - + Path socket = Paths.get(connector.getUnixSocket()); if (Files.exists(socket)) Files.delete(socket); - + 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 { int l = 0; - if (request.getContentLength()!=0) + if (request.getContentLength() != 0) { InputStream in = request.getInputStream(); byte[] buffer = new byte[4096]; int r = 0; - while (r>=0) + while (r >= 0) { l += r; r = in.read(buffer); @@ -69,15 +66,15 @@ public class UnixSocketServer } baseRequest.setHandled(true); response.setStatus(200); - response.getWriter().write("Hello World "+new Date() + "\r\n"); - response.getWriter().write("remote="+request.getRemoteAddr()+":"+request.getRemotePort()+"\r\n"); - response.getWriter().write("local ="+request.getLocalAddr()+":"+request.getLocalPort()+"\r\n"); - response.getWriter().write("read ="+l+"\r\n"); + response.getWriter().write("Hello World " + new Date() + "\r\n"); + response.getWriter().write("remote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\r\n"); + response.getWriter().write("local =" + request.getLocalAddr() + ":" + request.getLocalPort() + "\r\n"); + response.getWriter().write("read =" + l + "\r\n"); } }); - + server.start(); - + while (true) { Thread.sleep(5000); @@ -85,7 +82,7 @@ public class UnixSocketServer System.err.println("=============================="); connector.dumpStdErr(); } - + // server.join(); } } diff --git a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketTest.java b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketTest.java index 682d55c78d1..4cab52f6e46 100644 --- a/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketTest.java +++ b/jetty-unixsocket/src/test/java/org/eclipse/jetty/unixsocket/UnixSocketTest.java @@ -18,23 +18,15 @@ package org.eclipse.jetty.unixsocket; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.condition.OS.LINUX; -import static org.junit.jupiter.api.condition.OS.MAC; - import java.io.IOException; import java.io.InputStream; +import java.net.ConnectException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Date; import java.util.concurrent.ExecutionException; -import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -44,7 +36,6 @@ import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; @@ -54,6 +45,16 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledOnOs; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.condition.OS.LINUX; +import static org.junit.jupiter.api.condition.OS.MAC; + @EnabledOnOs({LINUX, MAC}) public class UnixSocketTest { @@ -68,94 +69,90 @@ public class UnixSocketTest { server = null; httpClient = null; - String unixSocketTmp = System.getProperty( "unix.socket.tmp" ); - if(StringUtil.isNotBlank( unixSocketTmp ) ) + String unixSocketTmp = System.getProperty("unix.socket.tmp"); + if (StringUtil.isNotBlank(unixSocketTmp)) + sockFile = Files.createTempFile(Paths.get(unixSocketTmp), "unix", ".sock"); + else + sockFile = Files.createTempFile("unix", ".sock"); + if (sockFile.toAbsolutePath().toString().length() > UnixSocketConnector.MAX_UNIX_SOCKET_PATH_LENGTH) { - sockFile = Files.createTempFile( Paths.get(unixSocketTmp), "unix", ".sock" ); - } else { - sockFile = Files.createTempFile("unix", ".sock" ); + Path tmp = Paths.get("/tmp"); + assumeTrue(Files.exists(tmp) && Files.isDirectory(tmp)); + sockFile = Files.createTempFile(tmp, "unix", ".sock"); } - assertTrue(Files.deleteIfExists(sockFile),"temp sock file cannot be deleted"); - + assertTrue(Files.deleteIfExists(sockFile), "temp sock file cannot be deleted"); } - + @AfterEach public void after() throws Exception { - if (httpClient!=null) + if (httpClient != null) httpClient.stop(); - if (server!=null) + if (server != null) server.stop(); - // Force delete, this will fail if UnixSocket was not closed properly in the implementation - FS.delete( sockFile); + if (sockFile != null) + assertFalse(Files.exists(sockFile)); } - + @Test public void testUnixSocket() throws Exception { server = new Server(); - HttpConnectionFactory http = new HttpConnectionFactory(); + UnixSocketConnector connector = new UnixSocketConnector(server, http); + connector.setUnixSocket(sockFile.toString()); + server.addConnector(connector); - UnixSocketConnector connector = new UnixSocketConnector( server, http ); - connector.setUnixSocket( sockFile.toString() ); - server.addConnector( connector ); - - server.setHandler( new AbstractHandler.ErrorDispatchHandler() + 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 { int l = 0; - if ( request.getContentLength() != 0 ) + if (request.getContentLength() != 0) { InputStream in = request.getInputStream(); byte[] buffer = new byte[4096]; int r = 0; - while ( r >= 0 ) + while (r >= 0) { l += r; - r = in.read( buffer ); + r = in.read(buffer); } } - log.info( "UnixSocketTest: request received" ); - baseRequest.setHandled( true ); - response.setStatus( 200 ); - response.getWriter().write( "Hello World " + new Date() + "\r\n" ); + log.info("UnixSocketTest: request received"); + baseRequest.setHandled(true); + response.setStatus(200); + response.getWriter().write("Hello World " + new Date() + "\r\n"); response.getWriter().write( - "remote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\r\n" ); + "remote=" + request.getRemoteAddr() + ":" + request.getRemotePort() + "\r\n"); response.getWriter().write( - "local =" + request.getLocalAddr() + ":" + request.getLocalPort() + "\r\n" ); - response.getWriter().write( "read =" + l + "\r\n" ); + "local =" + request.getLocalAddr() + ":" + request.getLocalPort() + "\r\n"); + response.getWriter().write("read =" + l + "\r\n"); } - } ); + }); server.start(); - httpClient = new HttpClient( new HttpClientTransportOverUnixSockets( sockFile.toString() ), null ); + httpClient = new HttpClient(new HttpClientTransportOverUnixSockets(sockFile.toString()), null); httpClient.start(); ContentResponse contentResponse = httpClient - .newRequest( "http://localhost" ) + .newRequest("http://localhost") .send(); - log.debug( "response from server: {}", contentResponse.getContentAsString() ); + log.debug("response from server: {}", contentResponse.getContentAsString()); - assertThat(contentResponse.getContentAsString(), containsString( "Hello World" )); + assertThat(contentResponse.getContentAsString(), containsString("Hello World")); } @Test public void testNotLocal() throws Exception - { - httpClient = new HttpClient( new HttpClientTransportOverUnixSockets( sockFile.toString() ), null ); + { + httpClient = new HttpClient(new HttpClientTransportOverUnixSockets(sockFile.toString()), null); httpClient.start(); - - ExecutionException e = assertThrows(ExecutionException.class, ()->{ - httpClient.newRequest( "http://google.com" ).send(); - }); - assertThat(e.getCause(), instanceOf(IOException.class)); - assertThat(e.getCause().getMessage(),containsString("UnixSocket cannot connect to google.com")); + + ExecutionException e = assertThrows(ExecutionException.class, () -> httpClient.newRequest("http://google.com").send()); + assertThat(e.getCause(), instanceOf(ConnectException.class)); } } diff --git a/pom.xml b/pom.xml index 822f5fce5ed..538a23be28b 100644 --- a/pom.xml +++ b/pom.xml @@ -1051,7 +1051,7 @@ com.github.jnr jnr-unixsocket - 0.20 + 0.22 junit diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java index b5ef43875c7..eea69f6462e 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/AsyncIOServletTest.java @@ -18,20 +18,6 @@ package org.eclipse.jetty.http.client; -import static java.nio.ByteBuffer.wrap; -import static org.eclipse.jetty.http.client.Transport.FCGI; -import static org.eclipse.jetty.util.BufferUtil.toArray; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -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.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -91,11 +77,24 @@ import org.eclipse.jetty.util.FuturePromise; import org.eclipse.jetty.util.log.StacklessLogging; import org.hamcrest.Matchers; import org.junit.jupiter.api.Assumptions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import static java.nio.ByteBuffer.wrap; +import static org.eclipse.jetty.http.client.Transport.FCGI; +import static org.eclipse.jetty.util.BufferUtil.toArray; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +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.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + public class AsyncIOServletTest extends AbstractTest { @Override @@ -395,12 +394,8 @@ public class AsyncIOServletTest extends AbstractTest { private final Logger logger = Log.getLogger(HttpClientLoadTest.class); @@ -178,7 +178,7 @@ public class HttpClientLoadTest extends AbstractTest failures) @@ -364,20 +364,18 @@ public class HttpClientLoadTest extends AbstractTest new LeakTrackingConnectionPool(destination, client.getMaxConnectionsPerDestination(), destination) { @Override diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java index 97eeb3727e8..b30d8509392 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java @@ -18,15 +18,6 @@ package org.eclipse.jetty.http.client; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -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.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; @@ -63,6 +54,15 @@ import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +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.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + public class HttpClientTest extends AbstractTest { @Override @@ -338,7 +338,7 @@ public class HttpClientTest extends AbstractTest { init(transport); // Only run this test for transports over TLS. - Assumptions.assumeTrue(scenario.isTransportSecure()); + Assumptions.assumeTrue(scenario.transport.isTlsBased()); scenario.startServer(new EmptyServerHandler()); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java index b14d6befef9..2b71e8ed587 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/RoundRobinConnectionPoolTest.java @@ -18,10 +18,6 @@ package org.eclipse.jetty.http.client; -import static org.hamcrest.MatcherAssert.assertThat; -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; @@ -43,6 +39,10 @@ import org.hamcrest.Matchers; 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.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class RoundRobinConnectionPoolTest extends AbstractTest { @Override @@ -98,7 +98,7 @@ public class RoundRobinConnectionPoolTest extends AbstractTest 0) + if (transport != Transport.UNIX_SOCKET && i > 0) assertThat(remotePorts.get(i - 1), Matchers.not(Matchers.equalTo(candidate))); } } @@ -109,7 +109,7 @@ public class RoundRobinConnectionPoolTest extends AbstractTest 0) + if (transport != Transport.UNIX_SOCKET && i > 0) assertThat(remotePorts.get(i - 1), Matchers.not(Matchers.equalTo(candidate))); } } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java index a68356ee08b..5c291ea781b 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/ServerTimeoutsTest.java @@ -18,18 +18,6 @@ package org.eclipse.jetty.http.client; -import static org.eclipse.jetty.http.client.Transport.FCGI; -import static org.eclipse.jetty.http.client.Transport.UNIX_SOCKET; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.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.assertTrue; - import java.io.IOException; import java.io.InterruptedIOException; import java.nio.ByteBuffer; @@ -69,6 +57,17 @@ import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import static org.eclipse.jetty.http.client.Transport.FCGI; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.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.assertTrue; + public class ServerTimeoutsTest extends AbstractTest { @Override @@ -552,8 +551,6 @@ public class ServerTimeoutsTest extends AbstractTest public void testAsyncWriteIdleTimeoutFires(Transport transport) throws Exception { init(transport); - // TODO work out why this test fails for UNIX_SOCKET - Assumptions.assumeFalse(scenario.transport == UNIX_SOCKET); CountDownLatch handlerLatch = new CountDownLatch(1); scenario.start(new AbstractHandler.ErrorDispatchHandler() diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java index fbd3dbf9e48..c38287de891 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java @@ -20,7 +20,7 @@ package org.eclipse.jetty.http.client; import java.util.Arrays; import java.util.EnumSet; -import java.util.Set; +import java.util.Locale; import java.util.stream.Stream; import org.eclipse.jetty.util.StringUtil; @@ -35,21 +35,16 @@ public class TransportProvider implements ArgumentsProvider String transports = System.getProperty(Transport.class.getName()); if (!StringUtil.isBlank(transports)) - { - return Arrays.stream(transports.split("\\s*,\\s*")) - .map(Transport::valueOf); - } + return Arrays.stream(transports.split("\\s*,\\s*")).map(Transport::valueOf); - // TODO #2014 too many test failures, don't test unix socket client for now. - // if (OS.IS_UNIX) - // return Transport.values(); + if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("linux")) + return Arrays.stream(Transport.values()); - return EnumSet.complementOf(EnumSet.of(Transport.UNIX_SOCKET)) - .stream(); + return EnumSet.complementOf(EnumSet.of(Transport.UNIX_SOCKET)).stream(); } @Override - public Stream provideArguments(ExtensionContext context) throws Exception + public Stream provideArguments(ExtensionContext context) { return getActiveTransports().map(Arguments::of); } diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java index 8eac0207a24..ee310f9b167 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java @@ -78,25 +78,21 @@ public class TransportScenario protected String servletPath = "/servlet"; protected HttpClient client; protected Path sockFile; - protected final BlockingQueue requestLog= new BlockingArrayQueue<>(); + protected final BlockingQueue requestLog = new BlockingArrayQueue<>(); public TransportScenario(final Transport transport) throws IOException { this.transport = transport; - - if(sockFile == null || !Files.exists( sockFile )) - { - Path target = MavenTestingUtils.getTargetPath(); - sockFile = Files.createTempFile(target,"unix", ".sock" ); - Files.delete( sockFile ); - } + Path target = MavenTestingUtils.getTargetPath(); + sockFile = Files.createTempFile(target, "unix", ".sock"); + Files.delete(sockFile); } public Optional getNetworkConnectorLocalPort() { if (connector instanceof ServerConnector) { - ServerConnector serverConnector = (ServerConnector) connector; + ServerConnector serverConnector = (ServerConnector)connector; return Optional.of(Integer.toString(serverConnector.getLocalPort())); } @@ -107,7 +103,7 @@ public class TransportScenario { if (connector instanceof ServerConnector) { - ServerConnector serverConnector = (ServerConnector) connector; + ServerConnector serverConnector = (ServerConnector)connector; return Optional.of(serverConnector.getLocalPort()); } @@ -116,7 +112,7 @@ public class TransportScenario public String getScheme() { - return isTransportSecure() ? "https" : "http"; + return transport.isTlsBased() ? "https" : "http"; } @Deprecated @@ -149,12 +145,12 @@ public class TransportScenario return new HttpClient(transport, sslContextFactory); } - public Connector newServerConnector(Server server) throws Exception + public Connector newServerConnector(Server server) { if (transport == Transport.UNIX_SOCKET) { - UnixSocketConnector unixSocketConnector = new UnixSocketConnector(server, provideServerConnectionFactory( transport )); - unixSocketConnector.setUnixSocket( sockFile.toString() ); + UnixSocketConnector unixSocketConnector = new UnixSocketConnector(server, provideServerConnectionFactory(transport)); + unixSocketConnector.setUnixSocket(sockFile.toString()); return unixSocketConnector; } return new ServerConnector(server, provideServerConnectionFactory(transport)); @@ -166,10 +162,7 @@ public class TransportScenario ret.append(getScheme()); ret.append("://localhost"); Optional localPort = getNetworkConnectorLocalPort(); - if (localPort.isPresent()) - { - ret.append(':').append(localPort.get()); - } + localPort.ifPresent(s -> ret.append(':').append(s)); return ret.toString(); } @@ -199,7 +192,7 @@ public class TransportScenario } case UNIX_SOCKET: { - return new HttpClientTransportOverUnixSockets( sockFile.toString() ); + return new HttpClientTransportOverUnixSockets(sockFile.toString()); } default: { @@ -254,13 +247,13 @@ public class TransportScenario throw new IllegalArgumentException(); } } - return result.toArray(new ConnectionFactory[result.size()]); + return result.toArray(new ConnectionFactory[0]); } public void setConnectionIdleTimeout(long idleTimeout) { if (connector instanceof AbstractConnector) - AbstractConnector.class.cast(connector).setIdleTimeout(idleTimeout); + ((AbstractConnector)connector).setIdleTimeout(idleTimeout); } public void setServerIdleTimeout(long idleTimeout) @@ -271,9 +264,10 @@ public class TransportScenario else setConnectionIdleTimeout(idleTimeout); } + public void start(Handler handler) throws Exception { - start(handler,null); + start(handler, null); } public void start(Handler handler, Consumer config) throws Exception @@ -304,7 +298,7 @@ public class TransportScenario client.setExecutor(clientThreads); client.setSocketAddressResolver(new SocketAddressResolver.Sync()); - if (config!=null) + if (config != null) config.accept(client); client.start(); @@ -337,7 +331,7 @@ public class TransportScenario server.setRequestLog((request, response) -> { int status = response.getCommittedMetaData().getStatus(); - requestLog.offer(String.format("%s %s %s %03d",request.getMethod(),request.getRequestURI(),request.getProtocol(),status)); + requestLog.offer(String.format("%s %s %s %03d", request.getMethod(), request.getRequestURI(), request.getProtocol(), status)); }); server.setHandler(handler); @@ -346,7 +340,7 @@ public class TransportScenario { server.start(); } - catch ( Exception e ) + catch (Exception e) { e.printStackTrace(); } @@ -382,25 +376,25 @@ public class TransportScenario { stopClient(); } - catch (Exception ignore) + catch (Exception x) { - LOG.ignore(ignore); + LOG.ignore(x); } try { stopServer(); } - catch (Exception ignore) + catch (Exception x) { - LOG.ignore(ignore); + LOG.ignore(x); } - if (sockFile!=null) + if (sockFile != null) { try { - Files.deleteIfExists( sockFile ); + Files.deleteIfExists(sockFile); } catch (IOException e) { @@ -408,6 +402,4 @@ public class TransportScenario } } } - - } From 0f6496abb3a01303a66f682effd17647719be469 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 19 Mar 2019 18:55:09 +0100 Subject: [PATCH 08/74] Issue #3180 - Review client support for Unix sockets. Fixed tests on Jenkins by shortening the Unix socket file name. Signed-off-by: Simone Bordet --- .../jetty/http/client/TransportScenario.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java index ee310f9b167..004df44e950 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.lang.management.ManagementFactory; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -60,11 +61,14 @@ import org.eclipse.jetty.unixsocket.UnixSocketConnector; import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets; import org.eclipse.jetty.util.BlockingArrayQueue; import org.eclipse.jetty.util.SocketAddressResolver; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.QueuedThreadPool; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + public class TransportScenario { private static final Logger LOG = Log.getLogger(TransportScenario.class); @@ -83,8 +87,22 @@ public class TransportScenario public TransportScenario(final Transport transport) throws IOException { this.transport = transport; - Path target = MavenTestingUtils.getTargetPath(); - sockFile = Files.createTempFile(target, "unix", ".sock"); + + Path unixSocketTmp; + String tmpProp = System.getProperty("unix.socket.tmp"); + if (StringUtil.isBlank(tmpProp)) + unixSocketTmp = MavenTestingUtils.getTargetPath(); + else + unixSocketTmp = Paths.get(tmpProp); + sockFile = Files.createTempFile(unixSocketTmp, "unix", ".sock"); + if (sockFile.toAbsolutePath().toString().length() > UnixSocketConnector.MAX_UNIX_SOCKET_PATH_LENGTH) + { + Files.delete(sockFile); + Path tmp = Paths.get("/tmp"); + assumeTrue(Files.exists(tmp) && Files.isDirectory(tmp)); + sockFile = Files.createTempFile(tmp, "unix", ".sock"); + } + Files.delete(sockFile); } From 4cbc933220ec1e65c0941662d1b20d6a56d6b128 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 19 Mar 2019 23:36:37 +0100 Subject: [PATCH 09/74] Issue #3180 - Review client support for Unix sockets. Updated code after reviews. Signed-off-by: Simone Bordet --- .../unixsocket/client/HttpClientTransportOverUnixSockets.java | 3 ++- .../java/org/eclipse/jetty/http/client/TransportProvider.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java index 989a3ed8b21..e2b6632846e 100644 --- a/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java +++ b/jetty-unixsocket/src/main/java/org/eclipse/jetty/unixsocket/client/HttpClientTransportOverUnixSockets.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.unixsocket.client; import java.io.IOException; +import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; @@ -67,7 +68,7 @@ public class HttpClientTransportOverUnixSockets extends HttpClientTransportOverH { InetAddress inet = address.getAddress(); if (!inet.isLoopbackAddress() && !inet.isLinkLocalAddress() && !inet.isSiteLocalAddress()) - throw new IOException("UnixSocket cannot connect to " + address.getHostString()); + throw new ConnectException("UnixSocket cannot connect to " + address.getHostString()); UnixSocketAddress unixAddress = new UnixSocketAddress(_unixSocket); channel = UnixSocketChannel.open(unixAddress); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java index c38287de891..0e95658c71a 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportProvider.java @@ -20,10 +20,10 @@ package org.eclipse.jetty.http.client; import java.util.Arrays; import java.util.EnumSet; -import java.util.Locale; import java.util.stream.Stream; import org.eclipse.jetty.util.StringUtil; +import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; @@ -37,7 +37,7 @@ public class TransportProvider implements ArgumentsProvider if (!StringUtil.isBlank(transports)) return Arrays.stream(transports.split("\\s*,\\s*")).map(Transport::valueOf); - if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("linux")) + if (OS.LINUX.isCurrentOs()) return Arrays.stream(Transport.values()); return EnumSet.complementOf(EnumSet.of(Transport.UNIX_SOCKET)).stream(); From 1accced62fb1776e8105f7750ac113c9846b7862 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 20 Mar 2019 18:18:55 +1100 Subject: [PATCH 10/74] Issue #3361 thread safe addHandler Added new thread safe methods deployHandler and undeployHandler Signed-off-by: Greg Wilkins --- .../deploy/bindings/StandardDeployer.java | 2 +- .../deploy/bindings/StandardUndeployer.java | 29 +----- .../handler/ContextHandlerCollection.java | 33 +++++++ .../server/handler/HandlerCollection.java | 6 +- .../jetty/util/thread/SerializedExecutor.java | 98 +++++++++++++++++++ .../util/thread/SerializedExecutorTest.java | 95 ++++++++++++++++++ 6 files changed, 233 insertions(+), 30 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java create mode 100644 jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java index dd58166c7be..7033f263214 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java @@ -40,6 +40,6 @@ public class StandardDeployer implements AppLifeCycle.Binding { throw new NullPointerException("No Handler created for App: " + app); } - app.getDeploymentManager().getContexts().addHandler(handler); + app.getDeploymentManager().getContexts().deployHandler(handler); } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java index ad5b0377799..a04462f1e05 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java @@ -21,10 +21,8 @@ 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; @@ -44,31 +42,6 @@ public class StandardUndeployer implements AppLifeCycle.Binding { 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); - } - } + chcoll.undeployHandler(handler); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index f5dafc1aff1..9f9d0da8deb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -40,6 +40,7 @@ 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. @@ -56,6 +57,7 @@ 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 Class _contextClass = ContextHandler.class; @@ -233,6 +235,7 @@ public class ContextHandlerCollection extends HandlerCollection * @param resourceBase the base (root) Resource * @return the ContextHandler just added */ + @Deprecated public ContextHandler addContext(String contextPath,String resourceBase) { try @@ -250,7 +253,37 @@ public class ContextHandlerCollection extends HandlerCollection } } + /* ------------------------------------------------------------ */ + /** + * Thread safe deploy of a Handler. + *

+ * 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)} and + * {@link #undeployHandler(Handler)} + *

+ * @param handler the handler to deploy + */ + public void deployHandler(Handler handler) + { + _serializedExecutor.execute(()-> addHandler(handler)); + } + /* ------------------------------------------------------------ */ + public void undeployHandler(Handler handler) + /** + * Thread safe undeploy of a Handler. + *

+ * 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)} and + * {@link #undeployHandler(Handler)} + *

+ * @param handler The handler to undeploy + */ + { + _serializedExecutor.execute(()-> removeHandler(handler)); + } /* ------------------------------------------------------------ */ /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index 0c950a30f19..1a8d7601aee 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -91,7 +91,11 @@ public class HandlerCollection extends AbstractHandlerContainer if (!_mutableWhenRunning && isStarted()) throw new IllegalStateException(STARTED); - while(!updateHandlers(_handlers.get(),newHandlers(handlers))); + while(true) + { + if(updateHandlers(_handlers.get(),newHandlers(handlers))) + break; + }; } /* ------------------------------------------------------------ */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java new file mode 100644 index 00000000000..2247b8c8060 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -0,0 +1,98 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util.thread; + +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jetty.util.log.Log; + +/** + * An executor than ensurers serial execution of submitted tasks. + *

+ * Callers of this execute will never block in the executor, but they may + * be required to either execute the task they submit or tasks submitted + * by other threads whilst they are executing tasks. + *

+ *

+ * This class was inspired by the public domain class + * NonBlockingMutexExecutor + *

+ */ +public class SerializedExecutor implements Executor +{ + final AtomicReference _tail = new AtomicReference<>(); + + @Override + public void execute(Runnable task) + { + Link link = new Link(task); + Link secondLast = _tail.getAndSet(link); + if (secondLast==null) + run(link); + else + secondLast._next.lazySet(link); + } + + protected void onError(Runnable task, Throwable t) + { + Log.getLogger(task.getClass()).warn(t); + } + + private void run(Link link) + { + while(true) + { + try + { + link._task.run(); + } + catch (Throwable t) + { + onError(link._task, t); + } + finally + { + // Are we the current the last Link? + if (_tail.compareAndSet(link, null)) + return; + + // not the last task, so its next link will eventually be set + Link next = link._next.get(); + while (next == null) + { + Thread.yield(); // Thread.onSpinWait(); + next = link._next.get(); + } + link = next; + } + } + } + + private class Link + { + final Runnable _task; + final AtomicReference _next = new AtomicReference<>(); + + public Link(Runnable task) + { + _task = task; + } + } +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java new file mode 100644 index 00000000000..9a6bab4237d --- /dev/null +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java @@ -0,0 +1,95 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util.thread; + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SerializedExecutorTest +{ + + @Test + public void test() throws Exception + { + int threads = 64; + int loops = 1000; + int depth = 100; + + AtomicInteger ran = new AtomicInteger(); + AtomicBoolean running = new AtomicBoolean(); + SerializedExecutor executor = new SerializedExecutor(); + final CountDownLatch start = new CountDownLatch(1); + final CountDownLatch stop = new CountDownLatch(threads); + final Random random = new Random(); + + for (int t=threads; t-->0;) + { + new Thread(()-> + { + try + { + start.await(); + + for (int l=loops; l-->0;) + { + final AtomicInteger d = new AtomicInteger(depth); + executor.execute(new Runnable() + { + @Override + public void run() + { + ran.incrementAndGet(); + if (!running.compareAndSet(false, true)) + throw new IllegalStateException(); + if (d.decrementAndGet() > 0) + executor.execute(this); + if (!running.compareAndSet(true, false)) + throw new IllegalStateException(); + } + }); + Thread.sleep(random.nextInt(5)); + } + } + catch(Throwable th) + { + th.printStackTrace(); + } + finally + { + stop.countDown(); + } + }).start(); + } + + start.countDown(); + assertTrue(stop.await(30, TimeUnit.SECONDS)); + assertThat(ran.get(), Matchers.is(threads*loops*depth)); + } + + +} \ No newline at end of file From 338f56ea938fc84b3d4aa4dad3a208b60daf19c9 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 20 Mar 2019 18:36:48 +1100 Subject: [PATCH 11/74] Issue #3361 thread safe addHandler Improved names and javadoc. Signed-off-by: Greg Wilkins --- .../jetty/server/handler/ContextHandlerCollection.java | 8 ++++++-- .../org/eclipse/jetty/util/thread/SerializedExecutor.java | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index 9f9d0da8deb..e2b127272eb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -260,12 +260,15 @@ public class ContextHandlerCollection extends HandlerCollection * 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)} and - * {@link #undeployHandler(Handler)} + * {@link #undeployHandler(Handler)}. + * The handler may be added after this call returns. *

* @param handler the handler to deploy */ public void deployHandler(Handler handler) { + if (handler.getServer()!=getServer()) + handler.setServer(getServer()); _serializedExecutor.execute(()-> addHandler(handler)); } @@ -277,7 +280,8 @@ public class ContextHandlerCollection extends HandlerCollection * 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)} and - * {@link #undeployHandler(Handler)} + * {@link #undeployHandler(Handler)}. + * The handler may be removed after this call returns. *

* @param handler The handler to undeploy */ diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java index 2247b8c8060..cb141187a0a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -37,13 +37,13 @@ import org.eclipse.jetty.util.log.Log; */ public class SerializedExecutor implements Executor { - final AtomicReference _tail = new AtomicReference<>(); + final AtomicReference _last = new AtomicReference<>(); @Override public void execute(Runnable task) { Link link = new Link(task); - Link secondLast = _tail.getAndSet(link); + Link secondLast = _last.getAndSet(link); if (secondLast==null) run(link); else @@ -69,8 +69,8 @@ public class SerializedExecutor implements Executor } finally { - // Are we the current the last Link? - if (_tail.compareAndSet(link, null)) + // Are we the current last Link? + if (_last.compareAndSet(link, null)) return; // not the last task, so its next link will eventually be set From 512886ae7ffc01033172b26de01e509558befad6 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 20 Mar 2019 10:51:16 +0100 Subject: [PATCH 12/74] Issue #3361 thread safe addHandler Code cleanup. Signed-off-by: Simone Bordet --- .../handler/ContextHandlerCollection.java | 26 ++++------- .../server/handler/HandlerCollection.java | 43 ++++++++----------- .../util/thread/SerializedExecutorTest.java | 23 +++++----- 3 files changed, 37 insertions(+), 55 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index e2b127272eb..cbdb52528d4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -43,8 +43,7 @@ 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. @@ -87,10 +86,8 @@ public class ContextHandlerCollection extends HandlerCollection protected Handlers newHandlers(Handler[] handlers) { if (handlers==null || handlers.length==0) - { return null; - } - + // Create map of contextPath to handler Branch // A branch is a Handler that could contain 0 or more ContextHandlers Map path2Branches = new HashMap<>(); @@ -133,7 +130,7 @@ public class ContextHandlerCollection extends HandlerCollection continue loop; } } - break loop; + break; } if (LOG.isDebugEnabled()) @@ -156,9 +153,6 @@ public class ContextHandlerCollection extends HandlerCollection } /* ------------------------------------------------------------ */ - /* - * @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 { @@ -167,9 +161,6 @@ public class ContextHandlerCollection extends HandlerCollection return; Mapping mapping = (Mapping)handlers; - if (mapping==null) - return; - HttpChannelState async = baseRequest.getHttpChannelState(); if (async.isAsync()) { @@ -230,7 +221,9 @@ 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 @@ -273,7 +266,6 @@ public class ContextHandlerCollection extends HandlerCollection } /* ------------------------------------------------------------ */ - public void undeployHandler(Handler handler) /** * Thread safe undeploy of a Handler. *

@@ -285,6 +277,7 @@ public class ContextHandlerCollection extends HandlerCollection *

* @param handler The handler to undeploy */ + public void undeployHandler(Handler handler) { _serializedExecutor.execute(()-> removeHandler(handler)); } @@ -298,7 +291,6 @@ public class ContextHandlerCollection extends HandlerCollection return _contextClass; } - /* ------------------------------------------------------------ */ /** * @param contextClass The class to use to add new Contexts @@ -338,7 +330,7 @@ public class ContextHandlerCollection extends HandlerCollection Set getContextPaths() { - Set set = new HashSet(); + Set set = new HashSet<>(); for (ContextHandler context:_contexts) set.add(context.getContextPath()); return set; @@ -380,7 +372,7 @@ public class ContextHandlerCollection extends HandlerCollection Mapping(Handler[] handlers, int capacity) { super(handlers); - _pathBranches = new ArrayTernaryTrie(false, capacity); + _pathBranches = new ArrayTernaryTrie<>(false, capacity); } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index 1a8d7601aee..c90be145f21 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -72,7 +72,7 @@ public class HandlerCollection extends AbstractHandlerContainer /* ------------------------------------------------------------ */ /** - * @return Returns the handlers. + * @return the array of handlers. */ @Override @ManagedAttribute(value="Wrapped handlers", readonly=true) @@ -84,7 +84,7 @@ public class HandlerCollection extends AbstractHandlerContainer /* ------------------------------------------------------------ */ /** - * @param handlers The handlers to set. + * @param handlers the array of handlers to set. */ public void setHandlers(Handler[] handlers) { @@ -93,9 +93,9 @@ public class HandlerCollection extends AbstractHandlerContainer while(true) { - if(updateHandlers(_handlers.get(),newHandlers(handlers))) + if (updateHandlers(_handlers.get(), newHandlers(handlers))) break; - }; + } } /* ------------------------------------------------------------ */ @@ -123,10 +123,11 @@ public class HandlerCollection extends AbstractHandlerContainer handler.setServer(getServer()); } - - if (_handlers.compareAndSet(old,handlers)) + if (_handlers.compareAndSet(old, handlers)) { - updateBeans(old==null?null:old._handlers,handlers==null?null:handlers._handlers); + Handler[] oldBeans = old == null ? null : old._handlers; + Handler[] newBeans = handlers == null ? null : handlers._handlers; + updateBeans(oldBeans, newBeans); return true; } return false; @@ -143,28 +144,21 @@ public class HandlerCollection extends AbstractHandlerContainer if (handlers==null) return; - Handler[] h = handlers._handlers; - MultiException mex=null; - - for (int i=0;i0;) + for (int t = threads; t-- > 0; ) { - new Thread(()-> + new Thread(() -> { try { start.await(); - for (int l=loops; l-->0;) + for (int l = loops; l-- > 0; ) { final AtomicInteger d = new AtomicInteger(depth); executor.execute(new Runnable() @@ -75,7 +74,7 @@ class SerializedExecutorTest Thread.sleep(random.nextInt(5)); } } - catch(Throwable th) + catch (Throwable th) { th.printStackTrace(); } @@ -88,8 +87,6 @@ class SerializedExecutorTest start.countDown(); assertTrue(stop.await(30, TimeUnit.SECONDS)); - assertThat(ran.get(), Matchers.is(threads*loops*depth)); + assertThat(ran.get(), Matchers.is(threads * loops * depth)); } - - -} \ No newline at end of file +} From 790dbbfaaa10809095da28c47537df1a1869b27a Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 21 Mar 2019 10:24:14 +1100 Subject: [PATCH 13/74] Issue #3361 thread safe addHandler Updates from review: - private fields - callbacks on deploy/undeploy - more deprecated javadoc Signed-off-by: Greg Wilkins --- .../deploy/bindings/StandardDeployer.java | 8 ++- .../deploy/bindings/StandardUndeployer.java | 14 ++--- .../handler/ContextHandlerCollection.java | 52 +++++++++++++++---- .../server/handler/HandlerCollection.java | 2 +- .../jetty/util/thread/SerializedExecutor.java | 24 ++++----- 5 files changed, 69 insertions(+), 31 deletions(-) diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java index 7033f263214..df52116a8ec 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java @@ -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.SharedBlockingCallback; public class StandardDeployer implements AppLifeCycle.Binding { @@ -37,9 +38,12 @@ public class StandardDeployer implements AppLifeCycle.Binding { ContextHandler handler = app.getContextHandler(); if (handler == null) - { throw new NullPointerException("No Handler created for App: " + app); + + try(SharedBlockingCallback.Blocker blocker = new SharedBlockingCallback().acquire()) + { + app.getDeploymentManager().getContexts().deployHandler(handler, blocker); + blocker.block(); } - app.getDeploymentManager().getContexts().deployHandler(handler); } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java index a04462f1e05..1996978a244 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java @@ -22,14 +22,10 @@ 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.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.SharedBlockingCallback; public class StandardUndeployer implements AppLifeCycle.Binding { - private static final Logger LOG = Log.getLogger(StandardUndeployer.class); - @Override public String[] getBindingTargets() { @@ -41,7 +37,11 @@ public class StandardUndeployer implements AppLifeCycle.Binding public void processBinding(Node node, App app) throws Exception { ContextHandler handler = app.getContextHandler(); - ContextHandlerCollection chcoll = app.getDeploymentManager().getContexts(); - chcoll.undeployHandler(handler); + + try(SharedBlockingCallback.Blocker blocker = new SharedBlockingCallback().acquire()) + { + app.getDeploymentManager().getContexts().undeployHandler(handler, blocker); + blocker.block(); + } } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index cbdb52528d4..6eb3666fa59 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -35,6 +35,7 @@ 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; @@ -58,6 +59,7 @@ public class ContextHandlerCollection extends HandlerCollection private static final Logger LOG = Log.getLogger(ContextHandlerCollection.class); private final SerializedExecutor _serializedExecutor = new SerializedExecutor(); + @Deprecated private Class _contextClass = ContextHandler.class; /* ------------------------------------------------------------ */ @@ -74,7 +76,10 @@ public class ContextHandlerCollection extends HandlerCollection } /* ------------------------------------------------------------ */ - @ManagedOperation("update the mapping of context path to context") + /** + * @deprecated Mapping is now always maintained on every set/add + */ + @ManagedOperation("update the mapping of context path to context (no longer required_") @Deprecated public void mapContexts() { @@ -227,6 +232,7 @@ public class ContextHandlerCollection extends HandlerCollection * @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) @@ -252,17 +258,29 @@ public class ContextHandlerCollection extends HandlerCollection *

* 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)} and - * {@link #undeployHandler(Handler)}. + * other calls to {@link #deployHandler(Handler, Callback)} and + * {@link #undeployHandler(Handler, Callback)}. * The handler may be added after this call returns. *

* @param handler the handler to deploy + * @param callback Called after handler has been added */ - public void deployHandler(Handler handler) + public void deployHandler(Handler handler, Callback callback) { if (handler.getServer()!=getServer()) handler.setServer(getServer()); - _serializedExecutor.execute(()-> addHandler(handler)); + _serializedExecutor.execute(()-> + { + try + { + addHandler(handler); + callback.succeeded(); + } + catch(Throwable th) + { + callback.failed(th); + } + }); } /* ------------------------------------------------------------ */ @@ -271,21 +289,35 @@ public class ContextHandlerCollection extends HandlerCollection *

* 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)} and - * {@link #undeployHandler(Handler)}. + * other calls to {@link #deployHandler(Handler,Callback)} and + * {@link #undeployHandler(Handler,Callback)}. * The handler may be removed after this call returns. *

* @param handler The handler to undeploy + * @param callback Called after handler has been removed */ - public void undeployHandler(Handler handler) + public void undeployHandler(Handler handler, Callback callback) { - _serializedExecutor.execute(()-> removeHandler(handler)); + _serializedExecutor.execute(()-> + { + try + { + removeHandler(handler); + callback.succeeded(); + } + catch(Throwable th) + { + callback.failed(th); + } + }); } /* ------------------------------------------------------------ */ /** * @return The class to use to add new Contexts + * @deprecated Unused convenience mechanism not used. */ + @Deprecated public Class getContextClass() { return _contextClass; @@ -294,7 +326,9 @@ public class ContextHandlerCollection extends HandlerCollection /* ------------------------------------------------------------ */ /** * @param contextClass The class to use to add new Contexts + * @deprecated Unused convenience mechanism not used. */ + @Deprecated public void setContextClass(Class contextClass) { if (contextClass ==null || !(ContextHandler.class.isAssignableFrom(contextClass))) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index c90be145f21..7e97e73d80e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -246,7 +246,7 @@ public class HandlerCollection extends AbstractHandlerContainer /* ------------------------------------------------------------ */ protected static class Handlers { - final Handler[] _handlers; + private final Handler[] _handlers; protected Handlers(Handler[] handlers) { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java index cb141187a0a..fb398d6bccd 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -69,26 +69,26 @@ public class SerializedExecutor implements Executor } finally { - // Are we the current last Link? - if (_last.compareAndSet(link, null)) - return; - - // not the last task, so its next link will eventually be set - Link next = link._next.get(); - while (next == null) + // Are we are not the current last Link? + if (!_last.compareAndSet(link, null)) { - Thread.yield(); // Thread.onSpinWait(); - next = link._next.get(); + // continue running the list, but may need to wait for the next link + Link next = link._next.get(); + while (next == null) + { + Thread.yield(); // Thread.onSpinWait(); + next = link._next.get(); + } + link = next; } - link = next; } } } private class Link { - final Runnable _task; - final AtomicReference _next = new AtomicReference<>(); + private final Runnable _task; + private final AtomicReference _next = new AtomicReference<>(); public Link(Runnable task) { From 265afacd3f3a64b026012ed6d5ec6658763a0194 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 21 Mar 2019 10:27:09 +1100 Subject: [PATCH 14/74] Issue #3361 thread safe addHandler Updates from review: - private fields Signed-off-by: Greg Wilkins --- .../java/org/eclipse/jetty/util/thread/SerializedExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java index fb398d6bccd..c1828cff59f 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -37,7 +37,7 @@ import org.eclipse.jetty.util.log.Log; */ public class SerializedExecutor implements Executor { - final AtomicReference _last = new AtomicReference<>(); + private final AtomicReference _last = new AtomicReference<>(); @Override public void execute(Runnable task) From 944636176ff25e04401c706bcc0d8627f820625c Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 21 Mar 2019 10:31:08 +1100 Subject: [PATCH 15/74] Issue #3361 thread safe addHandler Updates from review: - no return from finally Signed-off-by: Greg Wilkins --- .../jetty/util/thread/SerializedExecutor.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java index c1828cff59f..30f0446469c 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -37,17 +37,17 @@ import org.eclipse.jetty.util.log.Log; */ public class SerializedExecutor implements Executor { - private final AtomicReference _last = new AtomicReference<>(); + final AtomicReference _tail = new AtomicReference<>(); @Override public void execute(Runnable task) { Link link = new Link(task); - Link secondLast = _last.getAndSet(link); - if (secondLast==null) + Link lastButOne = _tail.getAndSet(link); + if (lastButOne==null) run(link); else - secondLast._next.lazySet(link); + lastButOne._next.lazySet(link); } protected void onError(Runnable task, Throwable t) @@ -57,7 +57,7 @@ public class SerializedExecutor implements Executor private void run(Link link) { - while(true) + while(link!=null) { try { @@ -69,10 +69,12 @@ public class SerializedExecutor implements Executor } finally { - // Are we are not the current last Link? - if (!_last.compareAndSet(link, null)) + // Are we the current the last Link? + if (_tail.compareAndSet(link, null)) + link = null; + else { - // continue running the list, but may need to wait for the next link + // not the last task, so its next link will eventually be set Link next = link._next.get(); while (next == null) { @@ -87,8 +89,8 @@ public class SerializedExecutor implements Executor private class Link { - private final Runnable _task; - private final AtomicReference _next = new AtomicReference<>(); + final Runnable _task; + final AtomicReference _next = new AtomicReference<>(); public Link(Runnable task) { From 849920ce8788723766d98f3050265e33e23cd520 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 21 Mar 2019 10:32:43 +1100 Subject: [PATCH 16/74] Issue #3361 thread safe addHandler Updates from review: - private fields Signed-off-by: Greg Wilkins --- .../org/eclipse/jetty/util/thread/SerializedExecutor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java index 30f0446469c..173a4bfee17 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -37,7 +37,7 @@ import org.eclipse.jetty.util.log.Log; */ public class SerializedExecutor implements Executor { - final AtomicReference _tail = new AtomicReference<>(); + private final AtomicReference _tail = new AtomicReference<>(); @Override public void execute(Runnable task) @@ -89,8 +89,8 @@ public class SerializedExecutor implements Executor private class Link { - final Runnable _task; - final AtomicReference _next = new AtomicReference<>(); + private final Runnable _task; + private final AtomicReference _next = new AtomicReference<>(); public Link(Runnable task) { From f2e9f2f7b3c728b645191a49196e486363c88846 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Thu, 21 Mar 2019 17:11:47 +1100 Subject: [PATCH 17/74] Issue #3361 thread safe addHandler Updates from review: - private fields - better blocker for deployment Signed-off-by: Greg Wilkins --- .../deploy/bindings/StandardDeployer.java | 10 ++--- .../deploy/bindings/StandardUndeployer.java | 10 ++--- .../handler/ContextHandlerCollection.java | 40 ++++++++++++++----- .../server/handler/HandlerCollection.java | 5 +++ .../jetty/util/thread/SerializedExecutor.java | 11 +++++ 5 files changed, 53 insertions(+), 23 deletions(-) diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java index df52116a8ec..5fa840a794a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java @@ -22,7 +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.SharedBlockingCallback; +import org.eclipse.jetty.util.Callback; public class StandardDeployer implements AppLifeCycle.Binding { @@ -40,10 +40,8 @@ public class StandardDeployer implements AppLifeCycle.Binding if (handler == null) throw new NullPointerException("No Handler created for App: " + app); - try(SharedBlockingCallback.Blocker blocker = new SharedBlockingCallback().acquire()) - { - app.getDeploymentManager().getContexts().deployHandler(handler, blocker); - blocker.block(); - } + Callback.Completable blocker = new Callback.Completable(); + app.getDeploymentManager().getContexts().deployHandler(handler, blocker); + blocker.get(); } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java index 1996978a244..5381aa0a4d3 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java @@ -22,7 +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.SharedBlockingCallback; +import org.eclipse.jetty.util.Callback; public class StandardUndeployer implements AppLifeCycle.Binding { @@ -38,10 +38,8 @@ public class StandardUndeployer implements AppLifeCycle.Binding { ContextHandler handler = app.getContextHandler(); - try(SharedBlockingCallback.Blocker blocker = new SharedBlockingCallback().acquire()) - { - app.getDeploymentManager().getContexts().undeployHandler(handler, blocker); - blocker.block(); - } + Callback.Completable blocker = new Callback.Completable(); + app.getDeploymentManager().getContexts().undeployHandler(handler, blocker); + blocker.get(); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index 6eb3666fa59..c4c7119910a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -214,11 +214,11 @@ public class ContextHandlerCollection extends HandlerCollection } else { - if (mapping._handlers==null) + if (mapping.getHandlers()==null) return; - for (int i=0;i + + _serializedExecutor.execute(new SerializedExecutor.ErrorHandlingTask() { - try + @Override + public void run() { addHandler(handler); callback.succeeded(); } - catch(Throwable th) + + @Override + public void accept(Throwable throwable) { - callback.failed(th); + callback.failed(throwable); } }); } @@ -298,16 +302,19 @@ public class ContextHandlerCollection extends HandlerCollection */ public void undeployHandler(Handler handler, Callback callback) { - _serializedExecutor.execute(()-> + _serializedExecutor.execute(new SerializedExecutor.ErrorHandlingTask() { - try + @Override + public void run() { removeHandler(handler); callback.succeeded(); } - catch(Throwable th) + + @Override + public void accept(Throwable throwable) { - callback.failed(th); + callback.failed(throwable); } }); } @@ -408,5 +415,16 @@ public class ContextHandlerCollection extends HandlerCollection super(handlers); _pathBranches = new ArrayTernaryTrie<>(false, capacity); } + + public Map getContextBranches() + { + return _contextBranches; + } + + public Trie> getPathBranches() + { + return _pathBranches; + } + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index 7e97e73d80e..e00fe5eb52e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -252,5 +252,10 @@ public class HandlerCollection extends AbstractHandlerContainer { this._handlers = handlers; } + + public Handler[] getHandlers() + { + return _handlers; + } } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java index 173a4bfee17..73a67475525 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.util.thread; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; import org.eclipse.jetty.util.log.Log; @@ -52,6 +53,8 @@ public class SerializedExecutor implements Executor protected void onError(Runnable task, Throwable t) { + if (task instanceof ErrorHandlingTask) + ((ErrorHandlingTask)task).accept(t); Log.getLogger(task.getClass()).warn(t); } @@ -97,4 +100,12 @@ public class SerializedExecutor implements Executor _task = task; } } + + /** + * Error handling task + *

If a submitted task implements this interface, it will be passed + * any exceptions thrown when running the task.

+ */ + public interface ErrorHandlingTask extends Runnable, Consumer + {} } From 6fb243ff6c96714d997e71064c3e7b99d114d633 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Thu, 21 Mar 2019 14:42:42 +0100 Subject: [PATCH 18/74] Issue #3464 - Split SslContextFactory into Client and Server Introduced SslContextFactory subclasses Client and Server. Replaced all usages of SslContextFactory with either Client or Server as required. Refactored configuration checking so that warnings are not emitted when non necessary. Signed-off-by: Simone Bordet --- .../eclipse/jetty/embedded/Http2Server.java | 3 +- .../eclipse/jetty/embedded/LikeJettyXml.java | 2 +- .../jetty/embedded/ManyConnectors.java | 4 +- .../java/client/ConscryptHTTP2Client.java | 2 +- .../server/ConscryptHTTP2ServerTest.java | 27 ++-- .../alpn/java/client/JDK9HTTP2Client.java | 2 +- .../jetty/alpn/java/server/JDK9ALPNTest.java | 12 +- .../alpn/java/server/JDK9HTTP2Server.java | 2 +- .../alpn/java/client/OpenJDK8HTTP2Client.java | 2 +- .../openjdk8/server/OpenJDK8HTTP2Server.java | 2 +- .../client/AbstractHttpClientServerTest.java | 59 ++++++-- .../jetty/client/ExternalSiteTest.java | 12 +- .../client/HostnameVerificationTest.java | 13 +- .../jetty/client/HttpClientTLSTest.java | 56 +++++--- .../eclipse/jetty/client/HttpClientTest.java | 23 ++-- .../client/TLSServerConnectionCloseTest.java | 7 +- .../client/ssl/NeedWantClientAuthTest.java | 32 ++--- .../jetty/client/ssl/SslBytesClientTest.java | 2 +- .../jetty/client/ssl/SslBytesServerTest.java | 2 +- .../jetty/client/ssl/SslConnectionTest.java | 7 +- .../connectors/configuring-ssl.adoc | 2 +- .../proxy/DrupalHTTP2FastCGIProxyServer.java | 3 +- .../fcgi/server/proxy/TryFilesFilterTest.java | 9 +- .../WordPressHTTP2FastCGIProxyServer.java | 3 +- .../http2/alpn/tests/ALPNNegotiationTest.java | 20 +-- .../http2/alpn/tests/AbstractALPNTest.java | 20 ++- .../eclipse/jetty/http2/client/Client.java | 2 +- .../client/http/DirectHTTP2OverTLSTest.java | 24 +++- .../HttpClientTransportOverHTTP2Test.java | 20 +-- .../jetty/io/SocketChannelEndPointTest.java | 41 +++--- .../eclipse/jetty/io/SslConnectionTest.java | 5 +- .../jetty/io/SslEngineBehaviorTest.java | 12 +- .../jetty/jmx/ConnectorServerTest.java | 10 +- .../src/test/config/etc/jetty-ssl.xml | 3 +- .../osgi/test/TestJettyOSGiBootHTTP2.java | 2 +- .../test/TestJettyOSGiBootHTTP2Conscrypt.java | 2 +- .../osgi/test/TestJettyOSGiBootHTTP2JDK9.java | 2 +- .../eclipse/jetty/osgi/test/TestOSGiUtil.java | 9 +- .../jetty/proxy/ConnectHandlerSSLTest.java | 7 +- .../jetty/proxy/ForwardProxyServerTest.java | 4 +- .../proxy/ForwardProxyTLSServerTest.java | 24 ++-- .../src/main/config/etc/jetty-ssl-context.xml | 2 +- .../jetty/server/SslConnectionFactory.java | 4 +- .../jetty/server/ConnectionOpenCloseTest.java | 12 +- .../server/OptionalSslConnectionTest.java | 4 +- .../jetty/server/ThreadStarvationTest.java | 12 +- .../server/handler/DebugHandlerTest.java | 12 +- .../handler/SecuredRedirectHandlerTest.java | 10 +- .../jetty/server/ssl/SSLCloseTest.java | 4 +- .../jetty/server/ssl/SSLEngineTest.java | 14 +- .../ssl/SSLReadEOFAfterResponseTest.java | 8 +- .../SSLSelectChannelConnectorLoadTest.java | 8 +- .../ssl/SelectChannelServerSslTest.java | 20 +-- .../jetty/server/ssl/SlowClientsTest.java | 6 +- .../ssl/SniSslConnectionFactoryTest.java | 20 +-- .../server/ssl/SslConnectionFactoryTest.java | 15 +- .../ssl/SslContextFactoryReloadTest.java | 11 +- .../ssl/SslSelectChannelTimeoutTest.java | 4 +- .../jetty/server/ssl/SslUploadTest.java | 8 +- .../jetty/servlet/SSLAsyncIOServletTest.java | 9 +- .../jetty/util/ssl/SslContextFactory.java | 130 +++++++++++++++--- .../jetty/util/ssl/SslContextFactoryTest.java | 55 +++++--- .../client/DefaultHttpClientProvider.java | 2 +- .../simple/jetty-websocket-httpclient.xml | 4 +- .../common/scopes/SimpleContainerScope.java | 9 +- .../server/RedirectWebSocketClientTest.java | 19 +-- .../websocket/server/SimpleServletServer.java | 4 +- .../client/HttpChannelAssociationTest.java | 5 +- .../jetty/http/client/HttpClientTest.java | 22 +-- .../http/client/HttpClientTimeoutTest.java | 3 +- .../jetty/http/client/TransportScenario.java | 24 +++- .../jetty/test/HttpInputIntegrationTest.java | 3 +- .../src/test/resources/ssl.xml | 3 +- .../jetty/test/webapp/HTTP1Servlet.java | 2 +- .../jetty/test/webapp/HTTP2FromWebAppIT.java | 9 +- .../jetty/TestTransparentProxyServer.java | 3 +- 76 files changed, 571 insertions(+), 404 deletions(-) diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java index b61a5a2eba2..8f219520966 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java @@ -22,7 +22,6 @@ package org.eclipse.jetty.embedded; import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; -import java.nio.file.Files; import java.util.Date; import java.util.EnumSet; @@ -101,7 +100,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 sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(jetty_distro + "/demo-base/etc/keystore"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java index 3d5759e8d4e..3a56eff6da9 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java @@ -138,7 +138,7 @@ public class LikeJettyXml // === jetty-https.xml === // SSL Context Factory - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(jetty_home + "/../../../jetty-server/src/test/config/etc/keystore"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java index 638eea09823..1b0224bebf2 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java @@ -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 sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath()); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); diff --git a/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java b/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java index d1d714dfce6..be59eac69d4 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java +++ b/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2Client.java @@ -44,7 +44,7 @@ public class ConscryptHTTP2Client public static void main(String[] args) throws Exception { Security.addProvider(new OpenSSLProvider()); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Client(); sslContextFactory.setProvider("Conscrypt"); HTTP2Client client = new HTTP2Client(); client.addBean(sslContextFactory); diff --git a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java index cb621a020c3..2038d33bfc3 100644 --- a/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java +++ b/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java @@ -61,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 @@ -95,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); @@ -125,7 +136,7 @@ public class ConscryptHTTP2ServerTest public void testSimpleRequest() throws Exception { HTTP2Client h2Client = new HTTP2Client(); - HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(h2Client), newSslContextFactory()); + HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(h2Client), newClientSslContextFactory()); client.start(); try { diff --git a/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2Client.java b/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2Client.java index 9dbcf11e479..e1c576177dc 100644 --- a/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2Client.java +++ b/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2Client.java @@ -42,7 +42,7 @@ public class JDK9HTTP2Client public static void main(String[] args) throws Exception { HTTP2Client client = new HTTP2Client(); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Client(); client.addBean(sslContextFactory); client.start(); diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java index 8f74502dfe3..451786bcd09 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java +++ b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java @@ -18,9 +18,6 @@ package org.eclipse.jetty.alpn.java.server; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -47,6 +44,9 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; + public class JDK9ALPNTest { private Server server; @@ -68,7 +68,7 @@ public class JDK9ALPNTest private SslContextFactory newSslContextFactory() { - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); @@ -90,7 +90,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())) @@ -132,7 +132,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())) diff --git a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java index d2d2ce12536..5ada3b7c3b3 100644 --- a/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java +++ b/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java @@ -45,7 +45,7 @@ public class JDK9HTTP2Server httpsConfig.setSendServerVersion(true); httpsConfig.addCustomizer(new SecureRequestCustomizer()); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); diff --git a/jetty-alpn/jetty-alpn-openjdk8-client/src/test/java/org/eclipse/jetty/alpn/java/client/OpenJDK8HTTP2Client.java b/jetty-alpn/jetty-alpn-openjdk8-client/src/test/java/org/eclipse/jetty/alpn/java/client/OpenJDK8HTTP2Client.java index c41c14596c3..0b2f01d13bf 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-client/src/test/java/org/eclipse/jetty/alpn/java/client/OpenJDK8HTTP2Client.java +++ b/jetty-alpn/jetty-alpn-openjdk8-client/src/test/java/org/eclipse/jetty/alpn/java/client/OpenJDK8HTTP2Client.java @@ -42,7 +42,7 @@ public class OpenJDK8HTTP2Client public static void main(String[] args) throws Exception { HTTP2Client client = new HTTP2Client(); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Client(); client.addBean(sslContextFactory); client.start(); diff --git a/jetty-alpn/jetty-alpn-openjdk8-server/src/test/java/org/eclipse/jetty/alpn/openjdk8/server/OpenJDK8HTTP2Server.java b/jetty-alpn/jetty-alpn-openjdk8-server/src/test/java/org/eclipse/jetty/alpn/openjdk8/server/OpenJDK8HTTP2Server.java index 837a190f29a..4cb95fbdaf8 100644 --- a/jetty-alpn/jetty-alpn-openjdk8-server/src/test/java/org/eclipse/jetty/alpn/openjdk8/server/OpenJDK8HTTP2Server.java +++ b/jetty-alpn/jetty-alpn-openjdk8-server/src/test/java/org/eclipse/jetty/alpn/openjdk8/server/OpenJDK8HTTP2Server.java @@ -45,7 +45,7 @@ public class OpenJDK8HTTP2Server httpsConfig.setSendServerVersion(true); httpsConfig.addCustomizer(new SecureRequestCustomizer()); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java index dc47b51eebd..1a28496fa67 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java @@ -58,7 +58,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,12 +67,12 @@ public abstract class AbstractHttpClientServerTest protected void startClient(final Scenario scenario) throws Exception { - startClient(scenario, null,null); + startClient(scenario, null, null); } protected void startClient(final Scenario scenario, HttpClientTransport transport, Consumer config) throws Exception { - if (transport==null) + if (transport == null) transport = new HttpClientTransportOverHTTP(1); QueuedThreadPool executor = new QueuedThreadPool(); @@ -82,7 +82,7 @@ public abstract class AbstractHttpClientServerTest client.setExecutor(executor); client.setScheduler(scheduler); client.setSocketAddressResolver(new SocketAddressResolver.Sync()); - if (config!=null) + if (config != null) config.accept(client); client.start(); @@ -90,7 +90,7 @@ public abstract class AbstractHttpClientServerTest public HttpClient newHttpClient(Scenario scenario, HttpClientTransport transport) { - return new HttpClient(transport, scenario.newSslContextFactory()); + return new HttpClient(transport, scenario.newClientSslContextFactory()); } @AfterEach @@ -113,9 +113,10 @@ public abstract class AbstractHttpClientServerTest } } - public static class ScenarioProvider implements ArgumentsProvider { + public static class ScenarioProvider implements ArgumentsProvider + { @Override - public Stream provideArguments(ExtensionContext context) throws Exception + public Stream provideArguments(ExtensionContext context) { return Stream.of( new NormalScenario(), @@ -125,9 +126,10 @@ public abstract class AbstractHttpClientServerTest } } - public static class NonSslScenarioProvider implements ArgumentsProvider { + public static class NonSslScenarioProvider implements ArgumentsProvider + { @Override - public Stream provideArguments(ExtensionContext context) throws Exception + public Stream provideArguments(ExtensionContext context) { return Stream.of( new NormalScenario() @@ -138,12 +140,27 @@ public abstract class AbstractHttpClientServerTest public interface Scenario { - default SslContextFactory newSslContextFactory() { return null; } + SslContextFactory newClientSslContextFactory(); + + SslContextFactory newServerSslContextFactory(); + String getScheme(); } public static class NormalScenario implements Scenario { + @Override + public SslContextFactory newClientSslContextFactory() + { + return null; + } + + @Override + public SslContextFactory newServerSslContextFactory() + { + return null; + } + @Override public String getScheme() { @@ -160,15 +177,27 @@ public abstract class AbstractHttpClientServerTest public static class SslScenario implements Scenario { @Override - public SslContextFactory newSslContextFactory() + public SslContextFactory newClientSslContextFactory() + { + SslContextFactory.Client result = new SslContextFactory.Client(); + result.setEndpointIdentificationAlgorithm(null); + configure(result); + return result; + } + + @Override + public SslContextFactory 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 diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java index 50238673069..bcc72665111 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java @@ -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; @@ -36,6 +32,10 @@ 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 +44,7 @@ public class ExternalSiteTest @BeforeEach public void prepare() throws Exception { - client = new HttpClient(new SslContextFactory()); + client = new HttpClient(new SslContextFactory.Client()); client.start(); } @@ -94,7 +94,7 @@ public class ExternalSiteTest public void testExternalSSLSite() throws Exception { client.stop(); - client = new HttpClient(new SslContextFactory()); + client = new HttpClient(new SslContextFactory.Client()); client.start(); String host = "api-3t.paypal.com"; diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java index 706471023fd..ba01b211c7d 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java @@ -18,10 +18,6 @@ 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; @@ -40,11 +36,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 +51,7 @@ import org.junit.jupiter.api.Test; @Disabled public class HostnameVerificationTest { - private SslContextFactory clientSslContextFactory = new SslContextFactory(); + private SslContextFactory clientSslContextFactory = new SslContextFactory.Client(); private Server server; private HttpClient client; private NetworkConnector connector; @@ -64,7 +63,7 @@ public class HostnameVerificationTest serverThreads.setName("server"); server = new Server(serverThreads); - SslContextFactory serverSslContextFactory = new SslContextFactory(); + SslContextFactory serverSslContextFactory = new SslContextFactory.Server(); serverSslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); serverSslContextFactory.setKeyStorePassword("storepwd"); connector = new ServerConnector(server, serverSslContextFactory); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java index 12edd273bfd..959e9ac2639 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java @@ -89,13 +89,25 @@ public class HttpClientTLSTest 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 @@ -110,7 +122,7 @@ public class HttpClientTLSTest @Test public void testNoCommonTLSProtocol() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); serverTLSFactory.setIncludeProtocols("TLSv1.3"); startServer(serverTLSFactory, new EmptyServerHandler()); @@ -124,7 +136,7 @@ public class HttpClientTLSTest } }); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory clientTLSFactory = createClientSslContextFactory(); clientTLSFactory.setIncludeProtocols("TLSv1.2"); startClient(clientTLSFactory); @@ -151,7 +163,7 @@ public class HttpClientTLSTest @Test public void testNoCommonTLSCiphers() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); serverTLSFactory.setIncludeCipherSuites("TLS_RSA_WITH_AES_128_CBC_SHA"); startServer(serverTLSFactory, new EmptyServerHandler()); @@ -165,7 +177,7 @@ public class HttpClientTLSTest } }); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory clientTLSFactory = createClientSslContextFactory(); clientTLSFactory.setExcludeCipherSuites(".*_SHA$"); startClient(clientTLSFactory); @@ -192,7 +204,7 @@ public class HttpClientTLSTest @Test public void testMismatchBetweenTLSProtocolAndTLSCiphersOnServer() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory 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"); @@ -208,7 +220,7 @@ public class HttpClientTLSTest } }); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory clientTLSFactory = createClientSslContextFactory(); startClient(clientTLSFactory); CountDownLatch clientLatch = new CountDownLatch(1); @@ -237,7 +249,7 @@ public class HttpClientTLSTest @Test public void testMismatchBetweenTLSProtocolAndTLSCiphersOnClient() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); startServer(serverTLSFactory, new EmptyServerHandler()); CountDownLatch serverLatch = new CountDownLatch(1); @@ -250,7 +262,7 @@ public class HttpClientTLSTest } }); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory 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"); @@ -279,7 +291,7 @@ public class HttpClientTLSTest @Test public void testHandshakeSucceeded() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); startServer(serverTLSFactory, new EmptyServerHandler()); CountDownLatch serverLatch = new CountDownLatch(1); @@ -292,7 +304,7 @@ public class HttpClientTLSTest } }); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory clientTLSFactory = createClientSslContextFactory(); startClient(clientTLSFactory); CountDownLatch clientLatch = new CountDownLatch(1); @@ -318,7 +330,7 @@ public class HttpClientTLSTest @Test public void testHandshakeSucceededWithSessionResumption() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); startServer(serverTLSFactory, new EmptyServerHandler()); AtomicReference serverSession = new AtomicReference<>(); @@ -331,7 +343,7 @@ public class HttpClientTLSTest } }); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory clientTLSFactory = createClientSslContextFactory(); startClient(clientTLSFactory); AtomicReference clientSession = new AtomicReference<>(); @@ -398,10 +410,10 @@ public class HttpClientTLSTest @Test public void testClientRawCloseDoesNotInvalidateSession() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); startServer(serverTLSFactory, new EmptyServerHandler()); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory clientTLSFactory = createClientSslContextFactory(); clientTLSFactory.start(); String host = "localhost"; @@ -453,13 +465,13 @@ public class HttpClientTLSTest @Test public void testServerRawCloseDetectedByClient() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); serverTLSFactory.start(); try (ServerSocket server = new ServerSocket(0)) { QueuedThreadPool clientThreads = new QueuedThreadPool(); clientThreads.setName("client"); - client = new HttpClient(createSslContextFactory()) + client = new HttpClient(createClientSslContextFactory()) { @Override protected ClientConnectionFactory newSslClientConnectionFactory(ClientConnectionFactory connectionFactory) @@ -523,10 +535,10 @@ public class HttpClientTLSTest @Test public void testHostNameVerificationFailure() throws Exception { - SslContextFactory serverTLSFactory = createSslContextFactory(); + SslContextFactory serverTLSFactory = createServerSslContextFactory(); startServer(serverTLSFactory, new EmptyServerHandler()); - SslContextFactory clientTLSFactory = createSslContextFactory(); + SslContextFactory 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. diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java index b32c271ff45..3fc5cc825f9 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java @@ -18,16 +18,6 @@ package org.eclipse.jetty.client; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -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.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.io.InputStream; import java.io.OutputStream; @@ -106,12 +96,21 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +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.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; + @ExtendWith(WorkDirExtension.class) public class HttpClientTest extends AbstractHttpClientServerTest { public WorkDir testdir; - @ParameterizedTest @ArgumentsSource(ScenarioProvider.class) public void testStoppingClosesConnections(Scenario scenario) throws Exception @@ -1529,7 +1528,7 @@ public class HttpClientTest extends AbstractHttpClientServerTest } }; } - }, scenario.newSslContextFactory()); + }, scenario.newClientSslContextFactory()); client.start(); final CountDownLatch latch = new CountDownLatch(2); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java index cdd6603dca1..e31911f32c2 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java @@ -18,8 +18,6 @@ package org.eclipse.jetty.client; -import static org.junit.jupiter.api.Assertions.assertEquals; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -42,14 +40,15 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class TLSServerConnectionCloseTest { private HttpClient client; private void startClient() throws Exception { - SslContextFactory sslContextFactory = new SslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(""); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("storepwd"); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java index 59fd76f42cd..b61ddf73ba6 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java @@ -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; @@ -43,9 +38,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. @@ -81,10 +80,9 @@ public class NeedWantClientAuthTest 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 +100,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 clientSSL = new SslContextFactory.Client(true); startClient(clientSSL); ContentResponse response = client.newRequest("https://localhost:" + connector.getLocalPort()) @@ -119,7 +117,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 +141,7 @@ public class NeedWantClientAuthTest } }); - SslContextFactory clientSSL = new SslContextFactory(true); + SslContextFactory clientSSL = new SslContextFactory.Client(true); clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks"); clientSSL.setKeyStorePassword("storepwd"); startClient(clientSSL); @@ -166,11 +164,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 clientSSL = new SslContextFactory.Client(true); startClient(clientSSL); CountDownLatch handshakeLatch = new CountDownLatch(1); client.addBean(new SslHandshakeListener() @@ -210,7 +208,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 +232,7 @@ public class NeedWantClientAuthTest } }); - SslContextFactory clientSSL = new SslContextFactory(true); + SslContextFactory clientSSL = new SslContextFactory.Client(true); clientSSL.setKeyStorePath("src/test/resources/client_keystore.jks"); clientSSL.setKeyStorePassword("storepwd"); startClient(clientSSL); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java index 836c935c002..ab2e72154c8 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesClientTest.java @@ -70,7 +70,7 @@ public class SslBytesClientTest extends SslBytesTest { threadPool = Executors.newCachedThreadPool(); - sslContextFactory = new SslContextFactory(true); + sslContextFactory = new SslContextFactory.Client(true); client = new HttpClient(sslContextFactory); client.setMaxConnectionsPerDestination(1); File keyStore = MavenTestingUtils.getTestResourceFile("keystore.jks"); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java index 904dc2e439d..0a21ba79dfb 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesServerTest.java @@ -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"); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java index cb657274128..c0952cebf60 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java @@ -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(); diff --git a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc index 6abde51fe5f..de454912ef4 100644 --- a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc +++ b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc @@ -790,7 +790,7 @@ To do this, first create a new `${jetty.base}/etc/tweak-ssl.xml` file (this can - + diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java index 67568980f73..3db6a4ece6a 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/DrupalHTTP2FastCGIProxyServer.java @@ -36,8 +36,7 @@ public class DrupalHTTP2FastCGIProxyServer { public static void main(String[] args) throws Exception { - SslContextFactory sslContextFactory = new SslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(""); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java index 3e52405c11d..afbb714dfaa 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java @@ -18,9 +18,6 @@ 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; @@ -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,8 +55,7 @@ public class TryFilesFilterTest connector = new ServerConnector(server); server.addConnector(connector); - SslContextFactory sslContextFactory = new SslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(""); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java index c10e94c1782..b35c0ca793f 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/WordPressHTTP2FastCGIProxyServer.java @@ -43,8 +43,7 @@ public class WordPressHTTP2FastCGIProxyServer { int tlsPort = 8443; - SslContextFactory sslContextFactory = new SslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(""); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); diff --git a/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java index aff9ebf3c41..4a6194eea48 100644 --- a/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java +++ b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java @@ -18,11 +18,6 @@ package org.eclipse.jetty.http2.alpn.tests; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -43,13 +38,18 @@ import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class ALPNNegotiationTest extends AbstractALPNTest { @Test public void testGentleCloseDuringHandshake() throws Exception { InetSocketAddress address = prepare(); - SslContextFactory sslContextFactory = newSslContextFactory(); + SslContextFactory sslContextFactory = newClientSslContextFactory(); sslContextFactory.start(); SSLEngine sslEngine = sslContextFactory.newSSLEngine(address); sslEngine.setUseClientMode(true); @@ -113,7 +113,7 @@ public class ALPNNegotiationTest extends AbstractALPNTest public void testAbruptCloseDuringHandshake() throws Exception { InetSocketAddress address = prepare(); - SslContextFactory sslContextFactory = newSslContextFactory(); + SslContextFactory sslContextFactory = newClientSslContextFactory(); sslContextFactory.start(); SSLEngine sslEngine = sslContextFactory.newSSLEngine(address); sslEngine.setUseClientMode(true); @@ -175,7 +175,7 @@ public class ALPNNegotiationTest extends AbstractALPNTest { InetSocketAddress address = prepare(); - SslContextFactory sslContextFactory = newSslContextFactory(); + SslContextFactory sslContextFactory = newClientSslContextFactory(); sslContextFactory.start(); SSLContext sslContext = sslContextFactory.getSslContext(); @@ -228,7 +228,7 @@ public class ALPNNegotiationTest extends AbstractALPNTest { InetSocketAddress address = prepare(); - SslContextFactory sslContextFactory = newSslContextFactory(); + SslContextFactory sslContextFactory = newClientSslContextFactory(); sslContextFactory.start(); SSLContext sslContext = sslContextFactory.getSslContext(); try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort())) @@ -280,7 +280,7 @@ public class ALPNNegotiationTest extends AbstractALPNTest { InetSocketAddress address = prepare(); - SslContextFactory sslContextFactory = newSslContextFactory(); + SslContextFactory sslContextFactory = newClientSslContextFactory(); sslContextFactory.start(); SSLContext sslContext = sslContextFactory.getSslContext(); try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort())) diff --git a/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java index 783298b9377..e955164816a 100644 --- a/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java +++ b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java @@ -49,7 +49,7 @@ public class AbstractALPNTest ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(); alpn.setDefaultProtocol(h1.getProtocol()); - connector = new ServerConnector(server, newSslContextFactory(), alpn, h1, h2); + connector = new ServerConnector(server, newServerSslContextFactory(), alpn, h1, h2); connector.setPort(0); connector.setIdleTimeout(30000); server.addConnector(connector); @@ -60,9 +60,22 @@ public class AbstractALPNTest return new InetSocketAddress("localhost", connector.getLocalPort()); } - protected SslContextFactory newSslContextFactory() + protected SslContextFactory.Server newServerSslContextFactory() + { + SslContextFactory.Server result = new SslContextFactory.Server(); + configureSslContextFactory(result); + return result; + } + + protected SslContextFactory.Client newClientSslContextFactory() + { + SslContextFactory.Client result = new SslContextFactory.Client(); + configureSslContextFactory(result); + return result; + } + + private void configureSslContextFactory(SslContextFactory sslContextFactory) { - SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks"); @@ -70,7 +83,6 @@ public class AbstractALPNTest sslContextFactory.setIncludeProtocols("TLSv1.2"); // The mandatory HTTP/2 cipher. sslContextFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"); - return sslContextFactory; } @AfterEach diff --git a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/Client.java b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/Client.java index 956a7b39c8f..b352cd336a6 100644 --- a/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/Client.java +++ b/jetty-http2/http2-client/src/test/java/org/eclipse/jetty/http2/client/Client.java @@ -43,7 +43,7 @@ public class Client public static void main(String[] args) throws Exception { HTTP2Client client = new HTTP2Client(); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Client(); client.addBean(sslContextFactory); client.start(); diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java index 53e0f530f5c..427d37cadc9 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/DirectHTTP2OverTLSTest.java @@ -68,7 +68,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); @@ -81,8 +81,7 @@ public class DirectHTTP2OverTLSTest clientThreads.setName("client"); HttpClientTransportOverHTTP2 transport = new HttpClientTransportOverHTTP2(new HTTP2Client()); transport.setUseALPN(false); - SslContextFactory sslContextFactory = newSslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(null); + SslContextFactory sslContextFactory = newClientSslContextFactory(); client = new HttpClient(transport, sslContextFactory); client.setExecutor(clientThreads); 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 diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java index 00b92695f73..b1656697c16 100644 --- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java +++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java @@ -18,15 +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; @@ -87,6 +78,15 @@ 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 @@ -601,7 +601,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest public void testExternalServer() throws Exception { HTTP2Client http2Client = new HTTP2Client(); - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Client(); HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory); Executor executor = new QueuedThreadPool(); httpClient.setExecutor(executor); diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java index 565ef8bf5d0..5f779f48635 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java @@ -18,15 +18,6 @@ package org.eclipse.jetty.io; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -73,6 +64,15 @@ 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.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + @SuppressWarnings("Duplicates") public class SocketChannelEndPointTest { @@ -626,24 +626,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; } @@ -651,11 +650,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; diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java index 9bc59170b11..587ab21a70c 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java @@ -60,7 +60,7 @@ 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 FutureCallback _writeCallback; @@ -92,7 +92,6 @@ public class SslConnectionTest return sslConnection; } - @Override protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey selectionKey) { @@ -133,7 +132,6 @@ public class SslConnectionTest } } - @BeforeEach public void initSSL() throws Exception { @@ -143,7 +141,6 @@ public class SslConnectionTest _sslCtxFactory.setKeyManagerPassword("keypwd"); _sslCtxFactory.setRenegotiationAllowed(true); _sslCtxFactory.setRenegotiationLimit(-1); - _sslCtxFactory.setEndpointIdentificationAlgorithm(null); startManager(); } diff --git a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java index ac6a8ac1d3a..d8bee115735 100644 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java +++ b/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java @@ -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(); } diff --git a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java index 0fd9ad74dd1..661f34f696b 100644 --- a/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java +++ b/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java @@ -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 *
@@ -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);
diff --git a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml
index 4a0e6245a83..908547f9af7 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml
+++ b/jetty-osgi/test-jetty-osgi/src/test/config/etc/jetty-ssl.xml
@@ -29,13 +29,12 @@
   
   
   
-  
+  
     
     /
     
     /
     
-    
     
     
     
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2.java
index fd392d6b201..89db1a7dcb9 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2.java
@@ -154,7 +154,7 @@ public class TestJettyOSGiBootHTTP2
             
             //set up client to do http2
             http2Client = new HTTP2Client();
-            SslContextFactory sslContextFactory = new SslContextFactory();
+            SslContextFactory sslContextFactory = new SslContextFactory.Client();
             sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
             sslContextFactory.setTrustStorePath(keys.getAbsolutePath());
             sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java
index 8edcaf8604b..c5716eb0b57 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java
@@ -139,7 +139,7 @@ public class TestJettyOSGiBootHTTP2Conscrypt
             File keys = path.resolve("etc").resolve("keystore").toFile();
 
             HTTP2Client http2Client = new HTTP2Client();
-            SslContextFactory sslContextFactory = new SslContextFactory();
+            SslContextFactory sslContextFactory = new SslContextFactory.Client();
             sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
             sslContextFactory.setTrustStorePath(keys.getAbsolutePath());
             sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java
index da10a161a0a..159b11ee54e 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestJettyOSGiBootHTTP2JDK9.java
@@ -133,7 +133,7 @@ public class TestJettyOSGiBootHTTP2JDK9
             
             //set up client to do http2
             http2Client = new HTTP2Client();
-            SslContextFactory sslContextFactory = new SslContextFactory();
+            SslContextFactory sslContextFactory = new SslContextFactory.Client();
             sslContextFactory.setKeyManagerPassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
             sslContextFactory.setTrustStorePath(keys.getAbsolutePath());
             sslContextFactory.setKeyStorePath(keys.getAbsolutePath());
diff --git a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java
index aa192ef7b64..f24850b6384 100644
--- a/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java
+++ b/jetty-osgi/test-jetty-osgi/src/test/java/org/eclipse/jetty/osgi/test/TestOSGiUtil.java
@@ -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;
@@ -273,10 +274,10 @@ public class TestOSGiUtil
        return bundleContext.getAllServiceReferences(service, null);
     }
 
-    protected static SslContextFactory newSslContextFactory()
+    protected static SslContextFactory newClientSslContextFactory()
     {
-        SslContextFactory sslContextFactory = new SslContextFactory(true);
-        sslContextFactory.setEndpointIdentificationAlgorithm("");
+        SslContextFactory sslContextFactory = new SslContextFactory.Client(true);
+        sslContextFactory.setEndpointIdentificationAlgorithm(null);
         return sslContextFactory;
     }
 
@@ -306,7 +307,7 @@ public class TestOSGiUtil
         }, null, null);
 
         // now test the servlet
-        HttpClient client = protocol.equals("https") ? new HttpClient(newSslContextFactory()) : new HttpClient();
+        HttpClient client = protocol.equals("https") ? new HttpClient(newClientSslContextFactory()) : new HttpClient();
         try
         {
             client.start();
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java
index c128b15e884..287c793ae92 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ConnectHandlerSSLTest.java
@@ -18,8 +18,6 @@
 
 package org.eclipse.jetty.proxy;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -43,10 +41,11 @@ 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.ssl.SslContextFactory;
-
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 public class ConnectHandlerSSLTest extends AbstractConnectHandlerTest
 {
     private SslContextFactory sslContextFactory;
@@ -54,7 +53,7 @@ public class ConnectHandlerSSLTest extends AbstractConnectHandlerTest
     @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");
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java
index d7ee8fa7dc2..34c625752d8 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyServerTest.java
@@ -62,7 +62,7 @@ public class ForwardProxyServerTest
         // no server SSL
         SslContextFactory scenario1 = null;
         // basic server SSL
-        SslContextFactory scenario2 = new SslContextFactory();
+        SslContextFactory scenario2 = new SslContextFactory.Server();
         scenario2.setKeyStorePath(keyStorePath);
         scenario2.setKeyStorePassword("storepwd");
         scenario2.setKeyManagerPassword("keypwd");
@@ -203,7 +203,7 @@ public class ForwardProxyServerTest
         startProxy();
 
         String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
-        SslContextFactory clientSsl = new SslContextFactory();
+        SslContextFactory clientSsl = new SslContextFactory.Client();
         clientSsl.setKeyStorePath(keyStorePath);
         clientSsl.setKeyStorePassword("storepwd");
         clientSsl.setKeyManagerPassword("keypwd");
diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java
index dfdbd3f2ca8..44c2690bc93 100644
--- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java
+++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyTLSServerTest.java
@@ -82,7 +82,7 @@ public class ForwardProxyTLSServerTest
         // no server SSL
         SslContextFactory scenario1 = null;
         // basic server SSL
-        SslContextFactory scenario2 = new SslContextFactory();
+        SslContextFactory scenario2 = new SslContextFactory.Server();
         scenario2.setKeyStorePath(keyStorePath);
         scenario2.setKeyStorePassword("storepwd");
         scenario2.setKeyManagerPassword("keypwd");
@@ -139,22 +139,27 @@ public class ForwardProxyTLSServerTest
 
     private static SslContextFactory newServerSslContextFactory()
     {
-        SslContextFactory sslContextFactory = new SslContextFactory();
-        String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
-        sslContextFactory.setKeyStorePath(keyStorePath);
-        sslContextFactory.setKeyStorePassword("storepwd");
-        sslContextFactory.setKeyManagerPassword("keypwd");
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
+        configureSslContextFactory(sslContextFactory);
         return sslContextFactory;
-
     }
 
     private static SslContextFactory newClientSslContextFactory()
     {
-        SslContextFactory sslContextFactory = newServerSslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Client();
+        configureSslContextFactory(sslContextFactory);
         sslContextFactory.setEndpointIdentificationAlgorithm(null);
         return sslContextFactory;
     }
 
+    private static void configureSslContextFactory(SslContextFactory sslContextFactory)
+    {
+        String keyStorePath = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
+        sslContextFactory.setKeyStorePath(keyStorePath);
+        sslContextFactory.setKeyStorePassword("storepwd");
+        sslContextFactory.setKeyManagerPassword("keypwd");
+    }
+
     @AfterEach
     public void stop() throws Exception
     {
@@ -629,9 +634,6 @@ 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.getProxyConfiguration().getProxies().add(new HttpProxy(proxyHost, proxyPort));
         httpClient.start();
diff --git a/jetty-server/src/main/config/etc/jetty-ssl-context.xml b/jetty-server/src/main/config/etc/jetty-ssl-context.xml
index ed8ec7db00a..2243ee57dfc 100644
--- a/jetty-server/src/main/config/etc/jetty-ssl-context.xml
+++ b/jetty-server/src/main/config/etc/jetty-ssl-context.xml
@@ -10,7 +10,7 @@
      https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites
 -->
 
-
+
   
   /
   
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
index 98470a9d617..8266f8d431c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java
@@ -53,8 +53,8 @@ public class SslConnectionFactory extends AbstractConnectionFactory
     public SslConnectionFactory(@Name("sslContextFactory") SslContextFactory 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);
     }
 
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java
index 159b54f4201..49f7c56b2c6 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java
@@ -18,11 +18,6 @@
 
 package org.eclipse.jetty.server;
 
-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.assertTrue;
-
 import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -49,6 +44,11 @@ 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.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 public class ConnectionOpenCloseTest extends AbstractHttpTest
 {
     @Test
@@ -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 sslContextFactory = new SslContextFactory.Server();
         File keystore = MavenTestingUtils.getTestResourceFile("keystore");
         sslContextFactory.setKeyStoreResource(Resource.newResource(keystore));
         sslContextFactory.setKeyStorePassword("storepwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/OptionalSslConnectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/OptionalSslConnectionTest.java
index 7a8e7a00e7e..71364386bde 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/OptionalSslConnectionTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/OptionalSslConnectionTest.java
@@ -52,7 +52,7 @@ public class OptionalSslConnectionTest
         server = new Server(serverThreads);
 
         String keystore = MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath();
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory 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())
         {
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java
index 3ddb18825cb..4827151c7e3 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java
@@ -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;
@@ -62,6 +57,11 @@ 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;
@@ -89,7 +89,7 @@ public class ThreadStarvationTest
         // HTTPS/SSL/TLS
         ConnectorProvider https = (server, acceptors, selectors) -> {
             Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore");
-            SslContextFactory sslContextFactory = new SslContextFactory();
+            SslContextFactory sslContextFactory = new SslContextFactory.Server();
             sslContextFactory.setKeyStorePath(keystorePath.toString());
             sslContextFactory.setKeyStorePassword("storepwd");
             sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java
index 2feb624dd67..945aa069205 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java
@@ -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;
@@ -58,6 +53,11 @@ 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()
@@ -89,7 +89,7 @@ public class DebugHandlerTest
         server.addConnector(httpConnector);
         
         File keystorePath = MavenTestingUtils.getTestResourceFile("keystore");
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystorePath.getAbsolutePath());
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SecuredRedirectHandlerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SecuredRedirectHandlerTest.java
index f95c4d43fb6..a2f7f7fd82a 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SecuredRedirectHandlerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SecuredRedirectHandlerTest.java
@@ -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 sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystore.getAbsolutePath());
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java
index 04033335e28..dbb5bb11a77 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java
@@ -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 sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStoreResource(Resource.newResource(keystore));
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
index 4f2b68aa842..ae6a5b6e0ec 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java
@@ -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 sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystore);
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLReadEOFAfterResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLReadEOFAfterResponseTest.java
index e6d027179a2..fd91e94725f 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLReadEOFAfterResponseTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLReadEOFAfterResponseTest.java
@@ -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;
@@ -46,6 +43,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 +54,7 @@ public class SSLReadEOFAfterResponseTest
     public void testReadEOFAfterResponse() throws Exception
     {
         File keystore = MavenTestingUtils.getTestResourceFile("keystore");
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStoreResource(Resource.newResource(keystore));
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java
index d1f68b93cd9..256fefbcd26 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java
@@ -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 sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystorePath);
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
index 7c1d0466aca..2ff8fa1137d 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
@@ -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 sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystorePath);
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SlowClientsTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SlowClientsTest.java
index f66fa3be0be..ec315bcbb3c 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SlowClientsTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SlowClientsTest.java
@@ -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 sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystore.getAbsolutePath());
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SniSslConnectionFactoryTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SniSslConnectionFactoryTest.java
index 7b39695b5a4..5c1e8c5c6d4 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SniSslConnectionFactoryTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SniSslConnectionFactoryTest.java
@@ -18,12 +18,6 @@
 
 package org.eclipse.jetty.server.ssl;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.startsWith;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -70,6 +64,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.containsString;
+import static org.hamcrest.Matchers.startsWith;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 public class SniSslConnectionFactoryTest
 {
     private Server _server;
@@ -118,7 +118,7 @@ public class SniSslConnectionFactoryTest
         if (!keystoreFile.exists())
             throw new FileNotFoundException(keystoreFile.getAbsolutePath());
 
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
         sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
         sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
@@ -224,7 +224,7 @@ public class SniSslConnectionFactoryTest
     {
         start("src/test/resources/keystore_sni.p12");
 
-        SslContextFactory clientContextFactory = new SslContextFactory(true);
+        SslContextFactory clientContextFactory = new SslContextFactory.Client(true);
         clientContextFactory.start();
         SSLSocketFactory factory = clientContextFactory.getSslContext().getSocketFactory();
         try (SSLSocket sslSocket = (SSLSocket)factory.createSocket("127.0.0.1", _port))
@@ -282,7 +282,7 @@ public class SniSslConnectionFactoryTest
     {
         start("src/test/resources/keystore_sni.p12");
 
-        SslContextFactory clientContextFactory = new SslContextFactory(true);
+        SslContextFactory clientContextFactory = new SslContextFactory.Client(true);
         clientContextFactory.start();
         SSLSocketFactory factory = clientContextFactory.getSslContext().getSocketFactory();
         try (SSLSocket sslSocket = (SSLSocket)factory.createSocket("127.0.0.1", _port))
@@ -360,7 +360,7 @@ public class SniSslConnectionFactoryTest
 
     private String getResponse(String sniHost, String reqHost, String cn) throws Exception
     {
-        SslContextFactory clientContextFactory = new SslContextFactory(true);
+        SslContextFactory clientContextFactory = new SslContextFactory.Client(true);
         clientContextFactory.start();
         SSLSocketFactory factory = clientContextFactory.getSslContext().getSocketFactory();
         try (SSLSocket sslSocket = (SSLSocket)factory.createSocket("127.0.0.1", _port))
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslConnectionFactoryTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslConnectionFactoryTest.java
index 03378b1864a..7171a4820de 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslConnectionFactoryTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslConnectionFactoryTest.java
@@ -18,11 +18,6 @@
 
 package org.eclipse.jetty.server.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.assertThrows;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -59,10 +54,14 @@ import org.eclipse.jetty.util.IO;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.hamcrest.Matchers;
 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.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
 public class SslConnectionFactoryTest
 {
     private Server _server;
@@ -87,7 +86,7 @@ public class SslConnectionFactoryTest
         https_config.addCustomizer(new SecureRequestCustomizer());
 
 
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
         sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
         sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
@@ -210,7 +209,7 @@ public class SslConnectionFactoryTest
 
     private String getResponse(String sniHost, String reqHost, String cn) throws Exception
     {
-        SslContextFactory clientContextFactory = new SslContextFactory(true);
+        SslContextFactory clientContextFactory = new SslContextFactory.Client(true);
         clientContextFactory.start();
         SSLSocketFactory factory = clientContextFactory.getSslContext().getSocketFactory();
 
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslContextFactoryReloadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslContextFactoryReloadTest.java
index 76ff9110bbc..3a3269d22a9 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslContextFactoryReloadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslContextFactoryReloadTest.java
@@ -18,10 +18,6 @@
 
 package org.eclipse.jetty.server.ssl;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -56,9 +52,12 @@ import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
 import org.eclipse.jetty.util.thread.Scheduler;
 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;
+
 public class SslContextFactoryReloadTest
 {
     public static final String KEYSTORE_1 = "src/test/resources/reload_keystore_1.jks";
@@ -72,7 +71,7 @@ public class SslContextFactoryReloadTest
     {
         server = new Server();
 
-        sslContextFactory = new SslContextFactory();
+        sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(KEYSTORE_1);
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyStoreType("JKS");
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java
index d71c89d9e82..0b02ac51b7a 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSelectChannelTimeoutTest.java
@@ -45,7 +45,7 @@ public class SslSelectChannelTimeoutTest extends ConnectorTimeoutTest
     public void init() throws Exception
     {
         String keystorePath = System.getProperty("basedir",".") + "/src/test/resources/keystore";
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystorePath);
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
@@ -64,7 +64,5 @@ public class SslSelectChannelTimeoutTest extends ConnectorTimeoutTest
         trustManagerFactory.init(keystore);
         __sslContext = SSLContext.getInstance("SSL");
         __sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
-
     }
-
 }
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
index 707e6f8c874..dcc8dc407a2 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java
@@ -18,9 +18,6 @@
 
 package org.eclipse.jetty.server.ssl;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -49,6 +46,9 @@ import org.junit.jupiter.api.BeforeAll;
 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;
+
 /**
  */
 public class SslUploadTest
@@ -62,7 +62,7 @@ public class SslUploadTest
     {
         File keystore = MavenTestingUtils.getTestResourceFile("keystore");
 
-        SslContextFactory sslContextFactory = new SslContextFactory();
+        SslContextFactory sslContextFactory = new SslContextFactory.Server();
         sslContextFactory.setKeyStorePath(keystore.getAbsolutePath());
         sslContextFactory.setKeyStorePassword("storepwd");
         sslContextFactory.setKeyManagerPassword("keypwd");
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java
index c10acb1a33b..e714ea8ecac 100644
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java
+++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/SSLAsyncIOServletTest.java
@@ -18,9 +18,6 @@
 
 package org.eclipse.jetty.servlet;
 
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -48,6 +45,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.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 public class SSLAsyncIOServletTest
 {
     public static Stream scenarios()
@@ -221,8 +221,7 @@ public class SSLAsyncIOServletTest
             Path keystorePath = MavenTestingUtils.getTestResourcePath("keystore.jks");
             Path truststorePath = MavenTestingUtils.getTestResourcePath("truststore.jks");
 
-            sslContextFactory = new SslContextFactory();
-            sslContextFactory.setEndpointIdentificationAlgorithm("");
+            sslContextFactory = new SslContextFactory.Server();
             sslContextFactory.setKeyStorePath(keystorePath.toString());
             sslContextFactory.setKeyStorePassword("storepwd");
             sslContextFactory.setTrustStorePath(truststorePath.toString());
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
index 71a06604501..fdc08e7324e 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java
@@ -86,10 +86,10 @@ import org.eclipse.jetty.util.security.CertificateValidator;
 import org.eclipse.jetty.util.security.Password;
 
 /**
- * SslContextFactory is used to configure SSL connectors
- * as well as HttpClient. It holds all SSL parameters and
- * creates SSL context based on these parameters to be
- * used by the SSL connectors.
+ * 

SslContextFactory is used to configure SSL parameters + * to be used by server and client connectors.

+ *

Use {@link Server} to configure server-side connectors, + * and {@link Client} to configure HTTP or WebSocket clients.

*/ @ManagedObject public class SslContextFactory extends AbstractLifeCycle implements Dumpable @@ -198,9 +198,11 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable private HostnameVerifier _hostnameVerifier; /** - * Construct an instance of SslContextFactory - * Default constructor for use in XmlConfiguration files + * Construct an instance of SslContextFactory with the default configuration. + * + * @deprecated use {@link Client#Client()} or {@link Server#Server()} instead */ + @Deprecated public SslContextFactory() { this(false); @@ -212,7 +214,9 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable * * @param trustAll whether to blindly trust all certificates * @see #setTrustAll(boolean) + * @deprecated use {@link Client#Client(boolean)} instead */ + @Deprecated public SslContextFactory(boolean trustAll) { this(trustAll, null); @@ -222,7 +226,9 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable * Construct an instance of SslContextFactory * * @param keyStorePath default keystore location + * @deprecated use {@link #setKeyStorePath(String)} instead */ + @Deprecated public SslContextFactory(String keyStorePath) { this(false, keyStorePath); @@ -249,21 +255,33 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable { load(); } - - secureConfigurationCheck(); + checkConfiguration(); } - protected void secureConfigurationCheck() + protected void checkConfiguration() { - if (isTrustAll()) - LOG_CONFIG.warn("Trusting all certificates configured for {}",this); - if (getEndpointIdentificationAlgorithm()==null) - LOG_CONFIG.warn("No Client EndPointIdentificationAlgorithm configured for {}",this); - SSLEngine engine = _factory._context.createSSLEngine(); customize(engine); SSLParameters supported = engine.getSSLParameters(); + checkProtocols(supported); + checkCiphers(supported); + } + + protected void checkTrustAll() + { + if (isTrustAll()) + LOG_CONFIG.warn("Trusting all certificates configured for {}", this); + } + + protected void checkEndPointIdentificationAlgorithm() + { + if (getEndpointIdentificationAlgorithm() == null) + LOG_CONFIG.warn("No Client EndPointIdentificationAlgorithm configured for {}", this); + } + + protected void checkProtocols(SSLParameters supported) + { for (String protocol : supported.getProtocols()) { for (String excluded : DEFAULT_EXCLUDED_PROTOCOLS) @@ -272,7 +290,10 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable LOG_CONFIG.warn("Protocol {} not excluded for {}", protocol, this); } } + } + protected void checkCiphers(SSLParameters supported) + { for (String suite : supported.getCipherSuites()) { for (String excludedSuiteRegex : DEFAULT_EXCLUDED_CIPHER_SUITES) @@ -417,9 +438,9 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable getExcludeCipherSuites(), getIncludeCipherSuites())); } - catch (NoSuchAlgorithmException ignore) + catch (NoSuchAlgorithmException x) { - LOG.ignore(ignore); + LOG.ignore(x); } } @@ -754,8 +775,10 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable /** * @return True if SSL needs client authentication. * @see SSLEngine#getNeedClientAuth() + * @deprecated use {@link Server#getNeedClientAuth()} instead */ @ManagedAttribute("Whether client authentication is needed") + @Deprecated public boolean getNeedClientAuth() { return _needClientAuth; @@ -764,7 +787,9 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable /** * @param needClientAuth True if SSL needs client authentication. * @see SSLEngine#getNeedClientAuth() + * @deprecated use {@link Server#setNeedClientAuth(boolean)} instead */ + @Deprecated public void setNeedClientAuth(boolean needClientAuth) { _needClientAuth = needClientAuth; @@ -773,8 +798,10 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable /** * @return True if SSL wants client authentication. * @see SSLEngine#getWantClientAuth() + * @deprecated use {@link Server#getWantClientAuth()} instead */ @ManagedAttribute("Whether client authentication is wanted") + @Deprecated public boolean getWantClientAuth() { return _wantClientAuth; @@ -783,7 +810,9 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable /** * @param wantClientAuth True if SSL wants client authentication. * @see SSLEngine#getWantClientAuth() + * @deprecated use {@link Server#setWantClientAuth(boolean)} instead */ + @Deprecated public void setWantClientAuth(boolean wantClientAuth) { _wantClientAuth = wantClientAuth; @@ -1110,6 +1139,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable * Deployments can be vulnerable to a man-in-the-middle attack if a EndpointIndentificationAlgorithm * is not set. * @param endpointIdentificationAlgorithm Set the endpointIdentificationAlgorithm + * @see #setHostnameVerifier(HostnameVerifier) */ public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm) { @@ -1198,7 +1228,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable } // Is SNI needed to select a certificate? - if (!_certWilds.isEmpty() || _certHosts.size()>1 || _certHosts.size()==1 && _aliasX509.size()>1) + if (!_certWilds.isEmpty() || _certHosts.size()>1 || (_certHosts.size()==1 && _aliasX509.size()>1)) { for (int idx = 0; idx < managers.length; idx++) { @@ -1761,10 +1791,14 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable sslParams.setCipherSuites(_selectedCipherSuites); if (_selectedProtocols != null) sslParams.setProtocols(_selectedProtocols); - if (getWantClientAuth()) - sslParams.setWantClientAuth(true); - if (getNeedClientAuth()) - sslParams.setNeedClientAuth(true); + if (this instanceof Server) + { + Server server = (Server)this; + if (server.getWantClientAuth()) + sslParams.setWantClientAuth(true); + if (server.getNeedClientAuth()) + sslParams.setNeedClientAuth(true); + } return sslParams; } @@ -1792,7 +1826,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509"); for (int i = 0; i < length; i++) { - byte bytes[] = javaxCerts[i].getEncoded(); + byte[] bytes = javaxCerts[i].getEncoded(); ByteArrayInputStream stream = new ByteArrayInputStream(bytes); javaCerts[i] = (X509Certificate)cf.generateCertificate(stream); } @@ -1953,4 +1987,56 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable return _x509; } } + + public static class Client extends SslContextFactory + { + public Client() + { + this(false); + } + + public Client(boolean trustAll) + { + super(trustAll); + } + + @Override + protected void checkConfiguration() + { + checkTrustAll(); + checkEndPointIdentificationAlgorithm(); + super.checkConfiguration(); + } + } + + public static class Server extends SslContextFactory + { + public Server() + { + setEndpointIdentificationAlgorithm(null); + } + + @Override + public boolean getWantClientAuth() + { + return super.getWantClientAuth(); + } + + public void setWantClientAuth(boolean wantClientAuth) + { + super.setWantClientAuth(wantClientAuth); + } + + @Override + public boolean getNeedClientAuth() + { + return super.getNeedClientAuth(); + } + + @Override + public void setNeedClientAuth(boolean needClientAuth) + { + super.setNeedClientAuth(needClientAuth); + } + } } diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java index 44e7d8a49be..3e602ae81c2 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java @@ -18,21 +18,6 @@ package org.eclipse.jetty.util.ssl; -import static org.eclipse.jetty.toolchain.test.matchers.RegexMatcher.matchesPattern; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.hamcrest.MatcherAssert.assertThat; -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.security.KeyStore; @@ -50,6 +35,22 @@ import org.eclipse.jetty.util.resource.Resource; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.eclipse.jetty.toolchain.test.matchers.RegexMatcher.matchesPattern; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +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.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class SslContextFactoryTest { private SslContextFactory cf; @@ -57,7 +58,7 @@ public class SslContextFactoryTest @BeforeEach public void setUp() throws Exception { - cf = new SslContextFactory(); + cf = new SslContextFactory.Server(); java.security.cert.CertPathBuilder certPathBuilder = java.security.cert.CertPathBuilder.getInstance("PKIX"); java.security.cert.PKIXRevocationChecker revocationChecker = (java.security.cert.PKIXRevocationChecker)certPathBuilder.getRevocationChecker(); @@ -325,18 +326,36 @@ public class SslContextFactoryTest @Test public void testNonDefaultKeyStoreTypeUsedForTrustStore() throws Exception { - cf = new SslContextFactory(); + cf = new SslContextFactory.Server(); cf.setKeyStoreResource(Resource.newSystemResource("keystore.p12")); cf.setKeyStoreType("pkcs12"); cf.setKeyStorePassword("storepwd"); cf.start(); cf.stop(); - cf = new SslContextFactory(); + cf = new SslContextFactory.Server(); cf.setKeyStoreResource(Resource.newSystemResource("keystore.jce")); cf.setKeyStoreType("jceks"); cf.setKeyStorePassword("storepwd"); cf.start(); cf.stop(); } + + @Test + public void testClientSslContextFactory() throws Exception + { + cf = new SslContextFactory.Client(); + cf.start(); + + assertEquals("HTTPS", cf.getEndpointIdentificationAlgorithm()); + } + + @Test + public void testServerSslContextFactory() throws Exception + { + cf = new SslContextFactory.Server(); + cf.start(); + + assertNull(cf.getEndpointIdentificationAlgorithm()); + } } diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/DefaultHttpClientProvider.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/DefaultHttpClientProvider.java index fb8c8856ba4..7ca6fd91784 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/DefaultHttpClientProvider.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/DefaultHttpClientProvider.java @@ -44,7 +44,7 @@ class DefaultHttpClientProvider if (sslContextFactory == null) { - sslContextFactory = new SslContextFactory(); + sslContextFactory = new SslContextFactory.Client(); sslContextFactory.setTrustAll(false); sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS"); } diff --git a/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml b/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml index 86ed90f948a..7f70642ad1a 100644 --- a/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml +++ b/jetty-websocket/websocket-client/src/test/resources/httpclient/simple/jetty-websocket-httpclient.xml @@ -3,7 +3,7 @@ - + false @@ -20,4 +20,4 @@ XmlBasedClient@
- \ No newline at end of file + diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java index e7d06adcdcf..8b00a84601b 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java @@ -48,8 +48,7 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke public SimpleContainerScope(WebSocketPolicy policy) { - this(policy, new MappedByteBufferPool(), new DecoratedObjectFactory()); - this.sslContextFactory = new SslContextFactory(); + this(policy, new MappedByteBufferPool()); } public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool) @@ -59,7 +58,7 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory) { - this(policy, bufferPool, (Executor) null, objectFactory); + this(policy, bufferPool, null, objectFactory); } public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, Executor executor, DecoratedObjectFactory objectFactory) @@ -83,9 +82,9 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke this.objectFactory = objectFactory; } - if(ssl == null) + if (ssl == null) { - this.sslContextFactory = new SslContextFactory(); + this.sslContextFactory = new SslContextFactory.Server(); } else { diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RedirectWebSocketClientTest.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RedirectWebSocketClientTest.java index b808feaadb4..58967216393 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RedirectWebSocketClientTest.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/RedirectWebSocketClientTest.java @@ -18,10 +18,6 @@ package org.eclipse.jetty.websocket.server; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; - import java.net.URI; import java.util.concurrent.Future; @@ -48,6 +44,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.is; +import static org.hamcrest.Matchers.notNullValue; + public class RedirectWebSocketClientTest { public static Server server; @@ -114,7 +114,7 @@ public class RedirectWebSocketClientTest private static SslContextFactory newSslContextFactory() { - SslContextFactory ssl = new SslContextFactory(); + SslContextFactory ssl = new SslContextFactory.Server(); ssl.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath()); ssl.setKeyStorePassword("storepwd"); ssl.setKeyManagerPassword("keypwd"); @@ -124,7 +124,10 @@ public class RedirectWebSocketClientTest @Test public void testRedirect() throws Exception { - SslContextFactory ssl = newSslContextFactory(); + SslContextFactory ssl = new SslContextFactory.Client(); + ssl.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath()); + ssl.setKeyStorePassword("storepwd"); + ssl.setKeyManagerPassword("keypwd"); ssl.setTrustAll(false); ssl.setEndpointIdentificationAlgorithm(null); HttpClient httpClient = new HttpClient(ssl); @@ -149,7 +152,7 @@ public class RedirectWebSocketClientTest } @WebSocket - public static class EmptyWebSocket { - + public static class EmptyWebSocket + { } } diff --git a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SimpleServletServer.java b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SimpleServletServer.java index bff61ac7491..ffba6ed5323 100644 --- a/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SimpleServletServer.java +++ b/jetty-websocket/websocket-server/src/test/java/org/eclipse/jetty/websocket/server/SimpleServletServer.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.websocket.server; import java.net.URI; + import javax.servlet.http.HttpServlet; import org.eclipse.jetty.http.HttpVersion; @@ -87,11 +88,10 @@ public class SimpleServletServer http_config.setSendServerVersion(true); http_config.setSendDateHeader(false); - sslContextFactory = new SslContextFactory(); + sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(MavenTestingUtils.getTestResourceFile("keystore").getAbsolutePath()); sslContextFactory.setKeyStorePassword("storepwd"); sslContextFactory.setKeyManagerPassword("keypwd"); - sslContextFactory.setEndpointIdentificationAlgorithm(null); // SSL HTTP Configuration HttpConfiguration https_config = new HttpConfiguration(http_config); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpChannelAssociationTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpChannelAssociationTest.java index f90c29f24c5..c2d27b49673 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpChannelAssociationTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpChannelAssociationTest.java @@ -65,7 +65,7 @@ public class HttpChannelAssociationTest extends AbstractTest init(transport); scenario.startServer(new EmptyServerHandler()); - scenario.client = new HttpClient(newHttpClientTransport(scenario, exchange -> false), scenario.sslContextFactory); + scenario.client = new HttpClient(newHttpClientTransport(scenario, exchange -> false), scenario.newClientSslContextFactory()); QueuedThreadPool clientThreads = new QueuedThreadPool(); clientThreads.setName("client"); scenario.client.setExecutor(clientThreads); @@ -90,8 +90,7 @@ public class HttpChannelAssociationTest extends AbstractTest scenario.startServer(new EmptyServerHandler()); long idleTimeout = 1000; - SslContextFactory sslContextFactory = scenario.newSslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(null); + SslContextFactory sslContextFactory = scenario.newClientSslContextFactory(); scenario.client = new HttpClient(newHttpClientTransport(scenario, exchange -> { // We idle timeout just before the association, diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java index 97eeb3727e8..9874017d17d 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java @@ -18,15 +18,6 @@ package org.eclipse.jetty.http.client; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -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.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; @@ -63,6 +54,15 @@ import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +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.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + public class HttpClientTest extends AbstractTest { @Override @@ -343,7 +343,9 @@ public class HttpClientTest extends AbstractTest scenario.startServer(new EmptyServerHandler()); // Use a default SslContextFactory, requests should fail because the server certificate is unknown. - scenario.client = scenario.newHttpClient(scenario.provideClientTransport(), new SslContextFactory()); + SslContextFactory.Client clientTLS = scenario.newClientSslContextFactory(); + clientTLS.setEndpointIdentificationAlgorithm("HTTPS"); + scenario.client = scenario.newHttpClient(scenario.provideClientTransport(), clientTLS); QueuedThreadPool clientThreads = new QueuedThreadPool(); clientThreads.setName("client"); scenario.client.setExecutor(clientThreads); diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java index 7aed306fd9e..1f90e2f18c7 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTimeoutTest.java @@ -251,8 +251,7 @@ public class HttpClientTimeoutTest extends AbstractTest scenario.startServer(new TimeoutHandler(2 * timeout)); AtomicBoolean sslIdle = new AtomicBoolean(); - SslContextFactory sslContextFactory = scenario.newSslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(null); + SslContextFactory sslContextFactory = scenario.newClientSslContextFactory(); scenario.client = new HttpClient(scenario.provideClientTransport(), sslContextFactory) { @Override diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java index 8eac0207a24..ba326fa835f 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/TransportScenario.java @@ -298,8 +298,7 @@ public class TransportScenario QueuedThreadPool clientThreads = new QueuedThreadPool(); clientThreads.setName("client"); clientThreads.setDetailedDump(true); - SslContextFactory sslContextFactory = newSslContextFactory(); - sslContextFactory.setEndpointIdentificationAlgorithm(null); + SslContextFactory sslContextFactory = newClientSslContextFactory(); client = newHttpClient(provideClientTransport(transport), sslContextFactory); client.setExecutor(clientThreads); client.setSocketAddressResolver(new SocketAddressResolver.Sync()); @@ -324,7 +323,7 @@ public class TransportScenario public void startServer(Handler handler) throws Exception { - sslContextFactory = newSslContextFactory(); + sslContextFactory = newServerSslContextFactory(); QueuedThreadPool serverThreads = new QueuedThreadPool(); serverThreads.setName("server"); serverThreads.setDetailedDump(true); @@ -352,16 +351,29 @@ public class TransportScenario } } - protected SslContextFactory newSslContextFactory() + protected SslContextFactory.Server newServerSslContextFactory() + { + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + configureSslContextFactory(sslContextFactory); + return sslContextFactory; + } + + protected 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.setTrustStorePath("src/test/resources/truststore.jks"); sslContextFactory.setTrustStorePassword("storepwd"); sslContextFactory.setUseCipherSuitesOrder(true); sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR); - return sslContextFactory; } public void stopClient() throws Exception diff --git a/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java b/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java index f718cd806bb..9d015ed4945 100644 --- a/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java +++ b/tests/test-integration/src/test/java/org/eclipse/jetty/test/HttpInputIntegrationTest.java @@ -101,11 +101,10 @@ public class HttpInputIntegrationTest // SSL Context Factory for HTTPS and HTTP/2 String jetty_distro = System.getProperty("jetty.distro","../../jetty-distribution/target/distribution"); - __sslContextFactory = new SslContextFactory(); + __sslContextFactory = new SslContextFactory.Server(); __sslContextFactory.setKeyStorePath(jetty_distro + "/../../../jetty-server/src/test/config/etc/keystore"); __sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); __sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); - __sslContextFactory.setEndpointIdentificationAlgorithm(null); // HTTPS Configuration __sslConfig = new HttpConfiguration(__config); diff --git a/tests/test-integration/src/test/resources/ssl.xml b/tests/test-integration/src/test/resources/ssl.xml index eecff79a0c1..b85cff469c4 100644 --- a/tests/test-integration/src/test/resources/ssl.xml +++ b/tests/test-integration/src/test/resources/ssl.xml @@ -1,10 +1,9 @@ - + / / - SSL_RSA_WITH_DES_CBC_SHA diff --git a/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java b/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java index cd1beb2a8ad..b73960341a2 100644 --- a/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java +++ b/tests/test-webapps/test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java @@ -54,7 +54,7 @@ public class HTTP1Servlet extends HttpServlet { try { - sslContextFactory = new SslContextFactory(true); + sslContextFactory = new SslContextFactory.Client(true); http2Client = new HTTP2Client(); http2Client.addBean(sslContextFactory); http2Client.start(); diff --git a/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java b/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java index d1fca3bc1a0..1185a9e4e6f 100644 --- a/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java +++ b/tests/test-webapps/test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java @@ -18,8 +18,6 @@ package org.eclipse.jetty.test.webapp; -import static org.junit.jupiter.api.Assertions.assertEquals; - import java.util.concurrent.TimeUnit; import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; @@ -36,9 +34,10 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; - import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class HTTP2FromWebAppIT { @Test @@ -46,7 +45,7 @@ public class HTTP2FromWebAppIT { Server server = new Server(); - SslContextFactory serverTLS = new SslContextFactory(); + SslContextFactory serverTLS = new SslContextFactory.Server(); serverTLS.setKeyStorePath("src/test/resources/keystore.jks"); serverTLS.setKeyStorePassword("storepwd"); serverTLS.setCipherComparator(new HTTP2Cipher.CipherComparator()); @@ -71,7 +70,7 @@ public class HTTP2FromWebAppIT try { - SslContextFactory clientTLS = new SslContextFactory(true); + SslContextFactory clientTLS = new SslContextFactory.Client(true); HttpClient client = new HttpClient(clientTLS); client.start(); diff --git a/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java b/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java index 002156a46fd..32ba3b9860c 100644 --- a/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java +++ b/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java @@ -82,7 +82,7 @@ public class TestTransparentProxyServer // SSL configurations - SslContextFactory sslContextFactory = new SslContextFactory(); + SslContextFactory sslContextFactory = new SslContextFactory.Server(); sslContextFactory.setKeyStorePath(jetty_root + "/jetty-server/src/main/config/etc/keystore"); sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"); sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g"); @@ -136,5 +136,4 @@ public class TestTransparentProxyServer server.start(); server.join(); } - } From 1c956dc470f5173985c0cab18f3ce8753d261987 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 26 Mar 2019 14:15:36 +1100 Subject: [PATCH 19/74] Issue #3361 thread safe addHandler Updates from review: - undeploy destroys context - reinstated mapContexts Signed-off-by: Greg Wilkins --- .../deploy/bindings/StandardUndeployer.java | 9 +++++--- .../jetty/server/handler/ContextHandler.java | 5 ++-- .../handler/ContextHandlerCollection.java | 22 ++++++++++++++---- .../server/handler/HandlerCollection.java | 3 ++- .../handler/ContextHandlerCollectionTest.java | 23 +++++++++---------- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java index 5381aa0a4d3..4b36a5e2834 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java @@ -18,10 +18,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.ContextHandler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.util.Callback; public class StandardUndeployer implements AppLifeCycle.Binding @@ -36,10 +38,11 @@ public class StandardUndeployer implements AppLifeCycle.Binding @Override public void processBinding(Node node, App app) throws Exception { - ContextHandler handler = app.getContextHandler(); - + ContextHandlerCollection contexts = app.getDeploymentManager().getContexts(); + ContextHandler context = app.getContextHandler(); Callback.Completable blocker = new Callback.Completable(); - app.getDeploymentManager().getContexts().undeployHandler(handler, blocker); + contexts.undeployHandler(context, blocker); blocker.get(); + context.destroy(); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java index b2fd1f42cb4..6b8fbcc8be5 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java @@ -1605,9 +1605,10 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu if (getServer() != null && (getServer().isStarting() || getServer().isStarted())) { - Handler[] contextCollections = getServer().getChildHandlersByClass(ContextHandlerCollection.class); + ContextHandlerCollection[] contextCollections = + (ContextHandlerCollection[])getServer().getChildHandlersByClass(ContextHandlerCollection.class); for (int h = 0; contextCollections != null && h < contextCollections.length; h++) - ((ContextHandlerCollection)contextCollections[h]).mapContexts(); + contextCollections[h].mapContexts(); } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java index c4c7119910a..fd3fbae21af 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java @@ -77,13 +77,27 @@ public class ContextHandlerCollection extends HandlerCollection /* ------------------------------------------------------------ */ /** - * @deprecated Mapping is now always maintained on every set/add + * 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 (no longer required_") - @Deprecated + @ManagedOperation("Update the mapping of context path to context") public void mapContexts() { - LOG.warn("mapContexts is Deprecated"); + _serializedExecutor.execute(()-> + { + while(true) + { + Handlers handlers = _handlers.get(); + if (handlers==null) + break; + if (updateHandlers(handlers, newHandlers(handlers.getHandlers()))) + break; + } + }); } /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java index e00fe5eb52e..e39077489ab 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HandlerCollection.java @@ -176,13 +176,14 @@ public class HandlerCollection extends AbstractHandlerContainer /** * Adds a handler. * This implementation adds the passed handler to the end of the existing collection of handlers. + * If the handler is already added, it is removed and readded */ public void addHandler(Handler handler) { while(true) { Handlers old = _handlers.get(); - Handlers handlers = newHandlers(ArrayUtil.addToArray(old==null?null:old._handlers, handler, Handler.class)); + Handlers handlers = newHandlers(ArrayUtil.addToArray(old==null?null:ArrayUtil.removeFromArray(old._handlers, handler), handler, Handler.class)); if (updateHandlers(old,handlers)) break; } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java index b0eda81f5c3..d6b04538afe 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java @@ -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) From 73f79751892b535fff906a6ce9437e8d9a6ca01f Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 27 Mar 2019 14:14:41 -0700 Subject: [PATCH 20/74] Issue #3489 - Allowing JAR directory references on Windows + Moving Resource.newResource() to later point Signed-off-by: Joakim Erdfelt --- .../eclipse/jetty/webapp/WebAppClassLoader.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java index 1805182e4dd..f7d165c4367 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppClassLoader.java @@ -279,20 +279,29 @@ public class WebAppClassLoader extends URLClassLoader while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken().trim(); - Resource resource= _context.newResource(token); - if (LOG.isDebugEnabled()) - LOG.debug("Path resource=" + resource); if(token.endsWith("*")) { if(token.length() > 1) { token = token.substring(0, token.length() - 1); + Resource resource= _context.newResource(token); + if (LOG.isDebugEnabled()) + LOG.debug("Glob Path resource=" + resource); resource= _context.newResource(token); addJars(resource); } - } else if (resource.isDirectory() && resource instanceof ResourceCollection) + return; + } + + Resource resource= _context.newResource(token); + if (LOG.isDebugEnabled()) + LOG.debug("Path resource=" + resource); + + if (resource.isDirectory() && resource instanceof ResourceCollection) + { addClassPath(resource); + } else { // Resolve file path if possible From 45b2c548b0f75c600362b0aec1b9f16e56d68735 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 27 Mar 2019 10:27:00 +1100 Subject: [PATCH 21/74] Issue #3106 - backport WebSocket connection stats from jetty-10 Signed-off-by: Lachlan Roberts --- .../tests/WebSocketConnectionStatsTest.java | 217 ++++++++++++++++++ .../jetty/websocket/common/Parser.java | 17 ++ .../io/AbstractWebSocketConnection.java | 24 ++ .../websocket/common/io/FrameFlusher.java | 24 ++ 4 files changed, 282 insertions(+) create mode 100644 jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketConnectionStatsTest.java diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketConnectionStatsTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketConnectionStatsTest.java new file mode 100644 index 00000000000..7899e156f6a --- /dev/null +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/WebSocketConnectionStatsTest.java @@ -0,0 +1,217 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.tests; + +import java.net.URI; +import java.nio.ByteBuffer; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.Connection; +import org.eclipse.jetty.io.ConnectionStatistics; +import org.eclipse.jetty.io.MappedByteBufferPool; +import org.eclipse.jetty.server.HttpConnection; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.common.CloseInfo; +import org.eclipse.jetty.websocket.common.Generator; +import org.eclipse.jetty.websocket.common.WebSocketFrame; +import org.eclipse.jetty.websocket.common.frames.TextFrame; +import org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection; +import org.eclipse.jetty.websocket.servlet.WebSocketServlet; +import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; +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.assertTrue; + +public class WebSocketConnectionStatsTest +{ + + @WebSocket + public static class ClientSocket + { + CountDownLatch closed = new CountDownLatch(1); + + String behavior; + + @OnWebSocketConnect + public void onOpen(Session session) + { + behavior = session.getPolicy().getBehavior().name(); + System.err.println(toString() + " Socket Connected: " + session); + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + System.err.println(toString() + " Socket Closed: " + statusCode + ":" + reason); + closed.countDown(); + } + + @OnWebSocketError + public void onError(Throwable cause) + { + cause.printStackTrace(System.err); + } + + @Override + public String toString() + { + return String.format("[%s@%s]", behavior, Integer.toHexString(hashCode())); + } + } + + @WebSocket + public static class EchoSocket extends ClientSocket + { + @OnWebSocketMessage + public void onMessage(Session session, String message) + { + session.getRemote().sendString(message, null); + } + } + + public static class MyWebSocketServlet extends WebSocketServlet + { + @Override + public void configure(WebSocketServletFactory factory) + { + factory.setCreator((req, resp)->new EchoSocket()); + } + } + + Server server; + WebSocketClient client; + ConnectionStatistics statistics; + CountDownLatch wsUpgradeComplete = new CountDownLatch(1); + CountDownLatch wsConnectionClosed = new CountDownLatch(1); + + @BeforeEach + public void start() throws Exception + { + statistics = new ConnectionStatistics() + { + @Override + public void onClosed(Connection connection) + { + super.onClosed(connection); + + if (connection instanceof AbstractWebSocketConnection) + wsConnectionClosed.countDown(); + else if (connection instanceof HttpConnection) + wsUpgradeComplete.countDown(); + } + }; + + server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(8080); + connector.addBean(statistics); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + contextHandler.addServlet(MyWebSocketServlet.class, "/testPath"); + server.setHandler(contextHandler); + + client = new WebSocketClient(); + + server.start(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + long getFrameByteSize(WebSocketFrame frame) + { + ByteBufferPool bufferPool = new MappedByteBufferPool(); + Generator generator = new Generator(WebSocketPolicy.newClientPolicy(), bufferPool); + ByteBuffer buffer = bufferPool.acquire(frame.getPayloadLength()+10, true); + int pos = BufferUtil.flipToFill(buffer); + generator.generateWholeFrame(frame, buffer); + return buffer.position() - pos; + } + + @Test + public void echoStatsTest() throws Exception + { + URI uri = URI.create("ws://localhost:8080/testPath"); + ClientSocket socket = new ClientSocket(); + Future connect = client.connect(socket, uri); + + final long numMessages = 10000; + final String msgText = "hello world"; + + long upgradeSentBytes; + long upgradeReceivedBytes; + + try (Session session = connect.get(5, TimeUnit.SECONDS)) + { + wsUpgradeComplete.await(5, TimeUnit.SECONDS); + upgradeSentBytes = statistics.getSentBytes(); + upgradeReceivedBytes = statistics.getReceivedBytes(); + + for (int i=0; i queue = new ArrayDeque<>(); private final List entries; private final List buffers; + private final LongAdder messagesOut = new LongAdder(); + private final LongAdder bytesOut = new LongAdder(); private boolean closed; private boolean canEnqueue = true; private Throwable terminated; @@ -141,6 +144,7 @@ public class FrameFlusher extends IteratingCallback { FrameEntry entry = queue.poll(); currentBatchMode = BatchMode.max(currentBatchMode, entry.batchMode); + messagesOut.increment(); // Force flush if we need to. if (entry.frame == FLUSH_FRAME) @@ -244,6 +248,16 @@ public class FrameFlusher extends IteratingCallback return Action.IDLE; } + int i = 0; + int bytes = 0; + ByteBuffer bufferArray[] = new ByteBuffer[buffers.size()]; + for (ByteBuffer bb : buffers) + { + bytes += bb.limit() - bb.position(); + bufferArray[i++] = bb; + } + bytesOut.add(bytes); + endPoint.write(this, buffers.toArray(new ByteBuffer[buffers.size()])); buffers.clear(); return Action.SCHEDULED; @@ -364,6 +378,16 @@ public class FrameFlusher extends IteratingCallback } } + public long getMessagesOut() + { + return messagesOut.longValue(); + } + + public long getBytesOut() + { + return bytesOut.longValue(); + } + @Override public String toString() { From 97ff7ed9c0506cdca5598b7363cd7df4bea4a583 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 28 Mar 2019 12:20:30 +1100 Subject: [PATCH 22/74] Issue #3106 - changes from review, adding javadoc Signed-off-by: Lachlan Roberts --- .../org/eclipse/jetty/websocket/common/Parser.java | 2 ++ .../common/io/AbstractWebSocketConnection.java | 12 ++++++++++++ .../jetty/websocket/common/io/FrameFlusher.java | 3 +++ 3 files changed, 17 insertions(+) diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java index 69b052f3e1e..fbdaef3bb80 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/Parser.java @@ -62,6 +62,8 @@ public class Parser private static final Logger LOG = Log.getLogger(Parser.class); private final WebSocketPolicy policy; private final ByteBufferPool bufferPool; + + // Stats (where a message is defined as a WebSocket frame) private final LongAdder messagesIn = new LongAdder(); private final LongAdder bytesIn = new LongAdder(); diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java index 69464fb1794..57dfd297ed6 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/AbstractWebSocketConnection.java @@ -675,24 +675,36 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp setInitialBuffer(prefilled); } + /** + * @return the number of WebSocket frames received over this connection + */ @Override public long getMessagesIn() { return parser.getMessagesIn(); } + /** + * @return the number of WebSocket frames sent over this connection + */ @Override public long getMessagesOut() { return flusher.getMessagesOut(); } + /** + * @return the number of bytes received over this connection + */ @Override public long getBytesIn() { return parser.getBytesIn(); } + /** + * @return the number of bytes frames sent over this connection + */ @Override public long getBytesOut() { diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java index 52623a1b02b..1027c7b3186 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/io/FrameFlusher.java @@ -53,8 +53,11 @@ public class FrameFlusher extends IteratingCallback private final Deque queue = new ArrayDeque<>(); private final List entries; private final List buffers; + + // Stats (where a message is defined as a WebSocket frame) private final LongAdder messagesOut = new LongAdder(); private final LongAdder bytesOut = new LongAdder(); + private boolean closed; private boolean canEnqueue = true; private Throwable terminated; From 8f29ea04cddd960b12144e054d5271aaf3a0148b Mon Sep 17 00:00:00 2001 From: lachan-roberts Date: Fri, 29 Mar 2019 15:01:37 +1100 Subject: [PATCH 23/74] Issue #3382 - implement Session.suspend() for jetty 10 websocket-api Signed-off-by: lachan-roberts --- .../eclipse/jetty/websocket/api/Session.java | 10 +- .../common/JettyWebSocketFrameHandler.java | 109 +++++++++-- .../websocket/common/WebSocketSession.java | 12 +- .../websocket/tests/SuspendResumeTest.java | 178 ++++++++++++++++++ 4 files changed, 291 insertions(+), 18 deletions(-) create mode 100644 jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java index af166e8b517..5c3e3a1a8a5 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java +++ b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java @@ -18,12 +18,12 @@ package org.eclipse.jetty.websocket.api; -import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; - import java.io.Closeable; import java.net.InetSocketAddress; import java.net.SocketAddress; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; + /** * Session represents an active link of communications with a Remote WebSocket Endpoint. */ @@ -164,7 +164,11 @@ public interface Session extends WebSocketPolicy, Closeable /** * Suspend the incoming read events on the connection. - * + *

+ * This should be called during the processing of a frame or message to successfully + * suspend read events before the next frame is received. Calling suspend outside of + * this will only suspend read events after the next frame has been received. + *

* @return the suspend token suitable for resuming the reading of data on the connection. */ SuspendToken suspend(); diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java index b9897d76a96..979534e23c4 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java @@ -45,6 +45,13 @@ import org.eclipse.jetty.websocket.core.WebSocketTimeoutException; public class JettyWebSocketFrameHandler implements FrameHandler { + private enum SuspendState + { + DEMANDING, + SUSPENDING, + SUSPENDED + } + private final Logger log; private final WebSocketContainer container; private final Object endpointInstance; @@ -72,6 +79,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler private MessageSink binarySink; private MessageSink activeMessageSink; private WebSocketSession session; + private SuspendState state = SuspendState.DEMANDING; public JettyWebSocketFrameHandler(WebSocketContainer container, Object endpointInstance, @@ -147,6 +155,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler callback.succeeded(); futureSession.complete(session); + demand(); } catch (Throwable cause) { @@ -155,11 +164,6 @@ public class JettyWebSocketFrameHandler implements FrameHandler } } - /** - * @see #onFrame(Frame,Callback) - */ - public final void onFrame(Frame frame) {} - @Override public void onFrame(Frame frame, Callback callback) { @@ -176,25 +180,34 @@ public class JettyWebSocketFrameHandler implements FrameHandler } } + // Demand after succeeding any received frame + Callback demandingCallback = Callback.from(()-> + { + callback.succeeded(); + demand(); + }, + callback::failed + ); + switch (frame.getOpCode()) { case OpCode.CLOSE: - onCloseFrame(frame, callback); + onCloseFrame(frame, demandingCallback); break; case OpCode.PING: - onPingFrame(frame, callback); + onPingFrame(frame, demandingCallback); break; case OpCode.PONG: - onPongFrame(frame, callback); + onPongFrame(frame, demandingCallback); break; case OpCode.TEXT: - onTextFrame(frame, callback); + onTextFrame(frame, demandingCallback); break; case OpCode.BINARY: - onBinaryFrame(frame, callback); + onBinaryFrame(frame, demandingCallback); break; case OpCode.CONTINUATION: - onContinuationFrame(frame, callback); + onContinuationFrame(frame, demandingCallback); break; } } @@ -337,6 +350,79 @@ public class JettyWebSocketFrameHandler implements FrameHandler acceptMessage(frame, callback); } + @Override + public boolean isDemanding() + { + return true; + } + + public void suspend() + { + synchronized (this) + { + switch(state) + { + case DEMANDING: + state = SuspendState.SUSPENDING; + break; + + case SUSPENDED: + case SUSPENDING: + throw new IllegalStateException("Already Suspended"); + + default: + throw new IllegalStateException(); + } + } + } + + public void resume() + { + synchronized (this) + { + switch(state) + { + case DEMANDING: + throw new IllegalStateException("Already Resumed"); + + case SUSPENDED: + state = SuspendState.DEMANDING; + session.getCoreSession().demand(1); + break; + + case SUSPENDING: + state = SuspendState.DEMANDING; + break; + + default: + throw new IllegalStateException(); + } + } + } + + private void demand() + { + synchronized (this) + { + switch(state) + { + case DEMANDING: + session.getCoreSession().demand(1); + break; + + case SUSPENDED: + throw new IllegalStateException("Suspended"); + + case SUSPENDING: + state = SuspendState.SUSPENDED; + break; + + default: + throw new IllegalStateException(); + } + } + } + static Throwable convertCause(Throwable cause) { if (cause instanceof MessageTooLargeException) @@ -362,5 +448,4 @@ public class JettyWebSocketFrameHandler implements FrameHandler return cause; } - } diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java index 50d937ee3ea..d6fd3406c02 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/WebSocketSession.java @@ -37,7 +37,7 @@ import org.eclipse.jetty.websocket.api.UpgradeResponse; import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.core.FrameHandler; -public class WebSocketSession extends AbstractLifeCycle implements Session, Dumpable +public class WebSocketSession extends AbstractLifeCycle implements Session, SuspendToken, Dumpable { private static final Logger LOG = Log.getLogger(WebSocketSession.class); private final FrameHandler.CoreSession coreSession; @@ -208,8 +208,14 @@ public class WebSocketSession extends AbstractLifeCycle implements Session, Dump @Override public SuspendToken suspend() { - // TODO: - return null; + frameHandler.suspend(); + return this; + } + + @Override + public void resume() + { + frameHandler.resume(); } public FrameHandler.CoreSession getCoreSession() diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java new file mode 100644 index 00000000000..3b75c1b7a3f --- /dev/null +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java @@ -0,0 +1,178 @@ +// +// ======================================================================== +// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.websocket.tests; + +import java.net.URI; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.BlockingArrayQueue; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.SuspendToken; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; +import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.server.JettyWebSocketServlet; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletContainerInitializer; +import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory; +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.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SuspendResumeTest +{ + @WebSocket + public static class EventSocket + { + private static final Logger LOG = Log.getLogger(EventSocket.class); + + + BlockingArrayQueue messages = new BlockingArrayQueue<>(); + CountDownLatch openLatch = new CountDownLatch(1); + CountDownLatch closeLatch = new CountDownLatch(1); + AtomicReference error = new AtomicReference<>(); + Session session; + + @OnWebSocketConnect + public void onConnect(Session session) + { + LOG.info("onConnect(): " + session); + this.session = session; + openLatch.countDown(); + } + + @OnWebSocketMessage + public void onMessage(String message) + { + LOG.info("onMessage(): " + message); + messages.offer(message); + } + + @OnWebSocketError + public void onError(Throwable t) + { + LOG.info("onError(): " + t); + error.compareAndSet(null, t); + } + + @OnWebSocketClose + public void onClose(int statusCode, String reason) + { + LOG.info("onClose(): " + statusCode + ":" + reason); + closeLatch.countDown(); + } + } + + public class UpgradeServlet extends JettyWebSocketServlet + { + @Override + public void configure(JettyWebSocketServletFactory factory) + { + factory.setCreator(((req, resp) -> serverSocket)); + } + } + + private Server server = new Server(); + private WebSocketClient client = new WebSocketClient(); + private EventSocket serverSocket = new EventSocket(); + private ServerConnector connector; + + @BeforeEach + public void start() throws Exception + { + connector = new ServerConnector(server); + connector.setPort(0); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); + contextHandler.setContextPath("/"); + server.setHandler(contextHandler); + contextHandler.addServlet(new ServletHolder(new UpgradeServlet()), "/test"); + + JettyWebSocketServletContainerInitializer.configureContext(contextHandler); + + server.start(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + client.stop(); + server.stop(); + } + + @Test + public void testSuspendResume() throws Exception + { + URI uri = new URI("ws://localhost:"+connector.getLocalPort()+"/test"); + EventSocket clientSocket = new EventSocket(); + Future connect = client.connect(clientSocket, uri); + connect.get(5, TimeUnit.SECONDS); + + // verify connection by sending a message from server to client + assertTrue(serverSocket.openLatch.await(5, TimeUnit.SECONDS)); + serverSocket.session.getRemote().sendStringByFuture("verification"); + assertThat(clientSocket.messages.poll(5, TimeUnit.SECONDS), is("verification")); + + // suspend the client so that no read events occur + SuspendToken suspendToken = clientSocket.session.suspend(); + + // verify client can still send messages + clientSocket.session.getRemote().sendStringByFuture("message-from-client"); + assertThat(serverSocket.messages.poll(5, TimeUnit.SECONDS), is("message-from-client")); + + // the first message is received as we had already demanded before suspend + serverSocket.session.getRemote().sendStringByFuture("first-message"); + assertThat(clientSocket.messages.poll(5, TimeUnit.SECONDS), is("first-message")); + + // the second message is not received as it is suspended + serverSocket.session.getRemote().sendStringByFuture("second-message"); + assertNull(clientSocket.messages.poll(2, TimeUnit.SECONDS)); + + // client should receive message after it resumes + suspendToken.resume(); + assertThat(clientSocket.messages.poll(5, TimeUnit.SECONDS), is("second-message")); + + // make sure both sides are closed + clientSocket.session.close(); + assertTrue(clientSocket.closeLatch.await(5, TimeUnit.SECONDS)); + assertTrue(serverSocket.closeLatch.await(5, TimeUnit.SECONDS)); + + // check no errors occurred + assertNull(clientSocket.error.get()); + assertNull(serverSocket.error.get()); + } +} From 3f81b469703700719be52d7dd345ffd724fa4541 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 29 Mar 2019 07:57:22 -0500 Subject: [PATCH 24/74] fix test on windows --- .../java/org/eclipse/jetty/servlet/CustomRequestLogTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java index d4cae832321..6ff83b0eccf 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java @@ -84,7 +84,7 @@ public class CustomRequestLogTest _connector.getResponse("GET /context/servlet/info HTTP/1.0\n\n"); String log = _entries.poll(5,TimeUnit.SECONDS); - assertThat(log, is("Filename: " + _tmpDir + "/servlet/info")); + assertThat(log, is("Filename: " + _tmpDir + File.pathSeparator + "servlet" + File.pathSeparator + "info")); } From 64f5718da3dc9aef51ebe2e4c97525f51e80b0c2 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 29 Mar 2019 08:08:29 -0500 Subject: [PATCH 25/74] fix test on windows --- .../java/org/eclipse/jetty/servlet/CustomRequestLogTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java index 6ff83b0eccf..4261010d5ba 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java @@ -84,7 +84,7 @@ public class CustomRequestLogTest _connector.getResponse("GET /context/servlet/info HTTP/1.0\n\n"); String log = _entries.poll(5,TimeUnit.SECONDS); - assertThat(log, is("Filename: " + _tmpDir + File.pathSeparator + "servlet" + File.pathSeparator + "info")); + assertThat(log, is("Filename: " + _tmpDir + File.separator + "servlet" + File.separator + "info")); } From 475331a547cc1d4e59761f820fd5795989cddca7 Mon Sep 17 00:00:00 2001 From: Jesse McConnell Date: Fri, 29 Mar 2019 08:28:47 -0500 Subject: [PATCH 26/74] really fix test on windows --- .../java/org/eclipse/jetty/servlet/CustomRequestLogTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java index 4261010d5ba..152a840ed90 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/CustomRequestLogTest.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.servlet; import java.io.IOException; +import java.io.File; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; From eaada1aa385a64020e1b3a70ee63f461253f4b7f Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Tue, 2 Apr 2019 12:38:34 +0200 Subject: [PATCH 27/74] Issue #3464 - Split SslContextFactory into Client and Server Updated documentation referencing the 2 new subclasses. Signed-off-by: Simone Bordet --- .../main/asciidoc/administration/jmx/using-jmx.adoc | 4 ++-- .../connectors/configuring-connectors.adoc | 2 +- .../configuring/connectors/configuring-ssl.adoc | 13 ++++++------- .../development/clients/http/http-client-intro.adoc | 4 ++-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/administration/jmx/using-jmx.adoc b/jetty-documentation/src/main/asciidoc/administration/jmx/using-jmx.adoc index e650ecb0f8b..3a6756935a9 100644 --- a/jetty-documentation/src/main/asciidoc/administration/jmx/using-jmx.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/jmx/using-jmx.adoc @@ -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"); diff --git a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc index 8b2a1864a28..f0adcb24ecd 100644 --- a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc +++ b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc @@ -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]. diff --git a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc index de454912ef4..f2702996b7e 100644 --- a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc +++ b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-ssl.adoc @@ -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"); diff --git a/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-intro.adoc b/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-intro.adoc index de8d0567f31..429f0444763 100644 --- a/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-intro.adoc +++ b/jetty-documentation/src/main/asciidoc/development/clients/http/http-client-intro.adoc @@ -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); From 9cda1ce0923b3b4a6fd325db1dad88d34cdbad9e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 3 Apr 2019 10:35:31 +1100 Subject: [PATCH 28/74] QueuedThreadPool bug - jobs disappearing on lifecycle stop as the QueuedThreadPool was being stopped, jobs could be taken out of the QueuedThreadPool job queue but then not run also cleaned up QueuedThreadPool _runnable code to simplify it Signed-off-by: Lachlan Roberts --- .../jetty/util/thread/QueuedThreadPool.java | 99 ++++++++++--------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java index 4d79a3fc4eb..aa469ce3243 100755 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java @@ -651,11 +651,6 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP _tryExecutor); } - private Runnable idleJobPoll() throws InterruptedException - { - return _jobs.poll(_idleTimeout, TimeUnit.MILLISECONDS); - } - private Runnable _runnable = new Runnable() { @Override @@ -663,21 +658,60 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP { boolean shrink = false; boolean ignore = false; + boolean idle = false; + try { Runnable job = _jobs.poll(); - if (job != null && _threadsIdle.get() == 0) - { startThreads(1); - } loop: - while (isRunning()) + while (true) { - // Job loop - while (job != null && isRunning()) + if (job == null) { + if (!idle) + { + idle = true; + _threadsIdle.incrementAndGet(); + } + + if (_idleTimeout <= 0) + job = _jobs.take(); + else + { + // maybe we should shrink? + int size = _threadsStarted.get(); + if (size > _minThreads) + { + long last = _lastShrink.get(); + long now = System.nanoTime(); + if (last == 0 || (now - last) > TimeUnit.MILLISECONDS.toNanos(_idleTimeout)) + { + if (_lastShrink.compareAndSet(last, now)) + { + _threadsStarted.decrementAndGet(); + shrink = true; + break loop; + } + } + } + + job = _jobs.poll(_idleTimeout, TimeUnit.MILLISECONDS); + } + } + + // run job + if (job != null) + { + if (idle) + { + idle = false; + if (_threadsIdle.decrementAndGet() == 0) + startThreads(1); + } + if (LOG.isDebugEnabled()) LOG.debug("run {}", job); runJob(job); @@ -688,46 +722,12 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP ignore = true; break loop; } - job = _jobs.poll(); } - // Idle loop - try - { - _threadsIdle.incrementAndGet(); + if (!isRunning()) + break loop; - while (isRunning() && job == null) - { - if (_idleTimeout <= 0) - job = _jobs.take(); - else - { - // maybe we should shrink? - final int size = _threadsStarted.get(); - if (size > _minThreads) - { - long last = _lastShrink.get(); - long now = System.nanoTime(); - if (last == 0 || (now - last) > TimeUnit.MILLISECONDS.toNanos(_idleTimeout)) - { - if (_lastShrink.compareAndSet(last, now) && _threadsStarted.compareAndSet(size, size - 1)) - { - shrink = true; - break loop; - } - } - } - job = idleJobPoll(); - } - } - } - finally - { - if (_threadsIdle.decrementAndGet() == 0) - { - startThreads(1); - } - } + job = _jobs.poll(); } } catch (InterruptedException e) @@ -741,6 +741,9 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP } finally { + if (idle) + _threadsIdle.decrementAndGet(); + if (!shrink && isRunning()) { if (!ignore) From 1caa349a206f13e3a023af3bc53da75b8a5dae33 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 3 Apr 2019 12:34:20 +1100 Subject: [PATCH 29/74] updated bom versions Signed-off-by: Greg Wilkins --- jetty-bom/pom.xml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 94d2e1cec4b..7deea067eb9 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -6,7 +6,7 @@ 4.0.0 jetty-bom - 9.3.25.v20180904 + 9.3.26-SNAPSHOT Jetty :: Bom Jetty BOM artifact http://www.eclipse.org/jetty @@ -103,17 +103,17 @@ org.eclipse.jetty cdi-core - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty cdi-servlet - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty cdi-websocket - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty @@ -138,12 +138,12 @@ org.eclipse.jetty jetty-gcloud-memcached-session-manager - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty jetty-gcloud-session-manager - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty @@ -228,17 +228,17 @@ org.eclipse.jetty jetty-osgi-boot - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty jetty-osgi-boot-jsp - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty jetty-osgi-boot-warurl - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty @@ -303,37 +303,37 @@ org.eclipse.jetty javax-websocket-client-impl - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty javax-websocket-server-impl - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty javax-websocket-api - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty javax-websocket-client - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty javax-websocket-common - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty javax-websocket-server - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty javax-websocket-servlet - 9.3.25-SNAPSHOT + 9.3.26-SNAPSHOT org.eclipse.jetty From 61b1a217deb8e435c5fb9ddc79e8039e96cee039 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 3 Apr 2019 12:34:46 +1100 Subject: [PATCH 30/74] updated release script versions Signed-off-by: Greg Wilkins --- scripts/release-jetty.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release-jetty.sh b/scripts/release-jetty.sh index a9f7f5ea6b9..697497991b2 100755 --- a/scripts/release-jetty.sh +++ b/scripts/release-jetty.sh @@ -141,7 +141,7 @@ if proceedyn "Are you sure you want to release using above? (y/N)" n; then # This is equivalent to 'mvn release:prepare' if proceedyn "Update project.versions for $VER_RELEASE? (Y/n)" y; then - mvn org.codehaus.mojo:versions-maven-plugin:2.5:set \ + mvn org.codehaus.mojo:versions-maven-plugin:2.7:set \ -DoldVersion="$VER_CURRENT" \ -DnewVersion="$VER_RELEASE" \ -DprocessAllModules=true From 7ec6d2fb32c89dd94037e982aca26971b1eface8 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 3 Apr 2019 13:06:51 +1100 Subject: [PATCH 31/74] Updating to version 9.3.26.v20190403 --- VERSION.txt | 7 +- aggregates/jetty-all-compact3/pom.xml | 2 +- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 74 +++++++++---------- jetty-cdi/cdi-core/pom.xml | 2 +- jetty-cdi/cdi-full-servlet/pom.xml | 2 +- jetty-cdi/cdi-servlet/pom.xml | 2 +- jetty-cdi/cdi-websocket/pom.xml | 2 +- jetty-cdi/pom.xml | 2 +- jetty-cdi/test-cdi-webapp/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-alpn-tests/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- jetty-monitor/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client-impl/pom.xml | 2 +- .../javax-websocket-server-impl/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-api/pom.xml | 2 +- jetty-websocket/websocket-client/pom.xml | 2 +- jetty-websocket/websocket-common/pom.xml | 2 +- jetty-websocket/websocket-server/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-continuation/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-gcloud-memcached-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-sessions/test-hash-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- 117 files changed, 158 insertions(+), 153 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 4187fa28817..ea67ac43e55 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,4 +1,9 @@ -jetty-9.3.26-SNAPSHOT +jetty-9.3.26.v20190403 - 03 April 2019 + + 3487 Test WebAppClassLoader does not definePackage + + 3461 gzip request customizer + + 3302 Supporting host:ip in X-Forwarded-For + + Updated ALPN to JDK 8u202. + + 2954 Report badmessage cause jetty-9.3.25.v20180904 - 04 September 2018 + 2135 Android 8.1 needs direct buffers for SSL/TLS to work diff --git a/aggregates/jetty-all-compact3/pom.xml b/aggregates/jetty-all-compact3/pom.xml index 0df0fdec62b..d49ac19e77c 100644 --- a/aggregates/jetty-all-compact3/pom.xml +++ b/aggregates/jetty-all-compact3/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../../pom.xml 4.0.0 diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index d74b2d63e07..1c0f8c63e21 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index a17a6d0cd9a..f8b383f190d 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 apache-jsp diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index 44a5d2fc3f9..a533edbf4fb 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 apache-jstl diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index ebe83497878..2474ee20b0c 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 76fc8951017..6cc9ecbc39e 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index edcb2dd8830..12a3da57f6f 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index a50d78bcbe6..aa77c6f06fe 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index de046ebe5bb..0e054c1f0e5 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml org.eclipse.jetty.examples diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index d39ff25320e..edfd9961600 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index 7d19310b9b5..cbae050494f 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index 13315a2844b..ba71797935e 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 8cef8ed4447..0bcae5db4c1 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index ef4517934ca..2d280537320 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index 18022ee86b6..e17a72c9eab 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-annotations diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index 9a39485be37..8b550690679 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 7deea067eb9..a907be62083 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -6,7 +6,7 @@ 4.0.0 jetty-bom - 9.3.26-SNAPSHOT + 9.3.26.v20190403 Jetty :: Bom Jetty BOM artifact http://www.eclipse.org/jetty @@ -98,7 +98,7 @@ org.eclipse.jetty jetty-annotations - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty @@ -118,22 +118,22 @@ org.eclipse.jetty jetty-client - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-continuation - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.fcgi fcgi-server - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.fcgi fcgi-server - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty @@ -148,82 +148,82 @@ org.eclipse.jetty jetty-hazelcast - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-http - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.http2 http2-client - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.http2 http2-common - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.http2 http2-hpack - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.http2 http2-http-client-transport - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty.http2 http2-server - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-http-spi - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-infinispan - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-io - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-jaas - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-jaspi - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-jmx - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-jndi - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-monitor - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-nosql - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty @@ -243,62 +243,62 @@ org.eclipse.jetty jetty-plus - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-proxy - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-quickstart - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-rewrite - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-security - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-server - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-servlet - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-servlets - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-spring - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-util - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-util-ajax - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-webapp - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty @@ -338,18 +338,18 @@ org.eclipse.jetty jetty-xml - 9.3.26-SNAPSHOT + 9.3.26.v20190403 org.eclipse.jetty jetty-distribution - 9.3.26-SNAPSHOT + 9.3.26.v20190403 zip org.eclipse.jetty jetty-distribution - 9.3.26-SNAPSHOT + 9.3.26.v20190403 tar.gz diff --git a/jetty-cdi/cdi-core/pom.xml b/jetty-cdi/cdi-core/pom.xml index baa9ef6577a..71fa6a6277c 100644 --- a/jetty-cdi/cdi-core/pom.xml +++ b/jetty-cdi/cdi-core/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 cdi-core diff --git a/jetty-cdi/cdi-full-servlet/pom.xml b/jetty-cdi/cdi-full-servlet/pom.xml index 8b8e0d0e4b1..85eb2163265 100644 --- a/jetty-cdi/cdi-full-servlet/pom.xml +++ b/jetty-cdi/cdi-full-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 cdi-full-servlet diff --git a/jetty-cdi/cdi-servlet/pom.xml b/jetty-cdi/cdi-servlet/pom.xml index 3e0fb793347..10696134004 100644 --- a/jetty-cdi/cdi-servlet/pom.xml +++ b/jetty-cdi/cdi-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 cdi-servlet diff --git a/jetty-cdi/cdi-websocket/pom.xml b/jetty-cdi/cdi-websocket/pom.xml index 271d181b7aa..8e8cdd3eb0d 100644 --- a/jetty-cdi/cdi-websocket/pom.xml +++ b/jetty-cdi/cdi-websocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 cdi-websocket diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index a62f9c15580..4224355a292 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 org.eclipse.jetty.cdi diff --git a/jetty-cdi/test-cdi-webapp/pom.xml b/jetty-cdi/test-cdi-webapp/pom.xml index 9e0c58fad51..473220a3043 100644 --- a/jetty-cdi/test-cdi-webapp/pom.xml +++ b/jetty-cdi/test-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 test-cdi-webapp diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index f770458a0cc..a397e39d45e 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index 3f73d4d2d87..83a5e353182 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 07ebe56d85d..056d6f44752 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 9ac219878ab..352c0784644 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index e99090460c1..f5ab74d8ff4 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 jetty-documentation Jetty :: Documentation diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index 89db76a3be2..bbbca428645 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index 99400921541..a1126e74d6c 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 008a7b87e23..79f96141d83 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml index 72c4c84c32e..42924d02166 100644 --- a/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index f93f0e2706e..f87cbfa7f34 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 4f06a0b3c2f..5e54e3f7cf0 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index 5eac93d3727..f5f11225fee 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-hazelcast diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index bb67e023e7a..f0fa86d0069 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index aec01c96acf..538886ec529 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-http diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml index df0de9987c9..2fddae32661 100644 --- a/jetty-http2/http2-alpn-tests/pom.xml +++ b/jetty-http2/http2-alpn-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 48523fa1c19..85d973564f9 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index b504eaec5ff..824ab8f9d97 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index ccc404d802a..9e3b62acb0b 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index 699a5b5e700..5335defcd4b 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 60641373251..30abe5f4903 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 5dd75aa50b3..6dc56079f83 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index 8bf01928bc6..8124a531103 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-infinispan diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index 6144f51fbcf..efc6c06577b 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -2,7 +2,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index 767592ca63c..ce51ed0ac42 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-jaas diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index d5dd7da3086..07ae7f4d694 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index 14110402cf2..e39d7ade2de 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index 8516b15f68f..b7c3072ca26 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-jndi diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 5c293cd3eed..529c769c84b 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index c4763ee8a73..75ee56efe6b 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-maven-plugin diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml index f38fb9932a3..53dda3b180d 100644 --- a/jetty-monitor/pom.xml +++ b/jetty-monitor/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-monitor diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 7d91403fc60..7e822e7319f 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-nosql diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index da3b2d72ac3..bf63f6fe3c1 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-osgi-alpn diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index 0ab52984bc9..5c0f67ee286 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 002ddf9df44..027b9615a0b 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index ef53810a31f..f94eb9d7526 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 4372e4f3c78..55118a74df8 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index 03f2da51ac1..d13121a9905 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 1640f817a28..2f39bca9c36 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index 1723824168f..5750951106f 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index 9ade1022c5e..b6fa8190b36 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 7ba73519d1e..8eafe3f1062 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index 843578387f2..b5063dd108a 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-plus diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index 890a8ba7883..dc7848f0d86 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-proxy diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index 83239bd5729..59929de5dc1 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 org.eclipse.jetty diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 6ff620dfbfe..919d013047d 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-rewrite diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index 09c9bdd9d34..d49f5b2bba5 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index eb847de5578..958b32e36b4 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 01fbb9648b3..69cabcdd8e4 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index 3d74eefec31..e52e6ede6be 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 2d9c6c7ca25..62a2b549545 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-servlets diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index e1ad8241f05..6871a291c18 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-spring diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index 93a923ae689..ad8c5223e4a 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-start diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 2fa2f5701d4..2db83000884 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 1597b0759dd..0b46d983460 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 95a93593abf..3050838902d 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-webapp diff --git a/jetty-websocket/javax-websocket-client-impl/pom.xml b/jetty-websocket/javax-websocket-client-impl/pom.xml index 7d993104b17..c0550138c2e 100644 --- a/jetty-websocket/javax-websocket-client-impl/pom.xml +++ b/jetty-websocket/javax-websocket-client-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/javax-websocket-server-impl/pom.xml b/jetty-websocket/javax-websocket-server-impl/pom.xml index ae29b521508..3be3be597ac 100644 --- a/jetty-websocket/javax-websocket-server-impl/pom.xml +++ b/jetty-websocket/javax-websocket-server-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 965eb238f09..9956e4bb2da 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml index 56d4e5a0e57..add02af9d0a 100644 --- a/jetty-websocket/websocket-api/pom.xml +++ b/jetty-websocket/websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index cbce40bc370..a85a8e98054 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index 492fba103ed..7434fcdaf4c 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml index 540374852b2..d01b680cf8d 100644 --- a/jetty-websocket/websocket-server/pom.xml +++ b/jetty-websocket/websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index b879bb67406..193ea425da9 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index fe34e0e299e..655d3188952 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 56f269deb2d..6be76865fed 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 Jetty :: Project http://www.eclipse.org/jetty pom diff --git a/tests/pom.xml b/tests/pom.xml index 40aa5ee39e3..6340c266dc1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml index e008e94edfb..6d8c71ed8a3 100644 --- a/tests/test-continuation/pom.xml +++ b/tests/test-continuation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index e0c777dd1c1..18e788bcbdb 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index f55e340594f..44eab34eca4 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index c959131c2af..d4a4d2e88df 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index 775b4ddb323..a35f2c246d1 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index 4421ac9148f..b6fcc5e7f79 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index 2a184fab528..c2ccf6d6f24 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 409e88aa309..3c942f5d075 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 6f16eff2a58..03d1005babc 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml b/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml index e31bb7cc343..eae51cb58ae 100644 --- a/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-gcloud-memcached-sessions Jetty Tests :: Sessions :: GCloud with Memcached diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index a9b261b85f7..c142c92c8fd 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index 6a99e907486..69a628787fb 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-hash-sessions Jetty Tests :: Sessions :: Hash diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index ac6db1b49e0..42442a5a071 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index 9c09f461cbc..d467788899c 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index d99300f9f16..b71442b3e2d 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 4bdab9696b1..91406768f51 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 2043cb730b8..010fa50b4e3 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index a6724ead9d5..36e0aec91ea 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index 9ba2b6ddf35..cd991e41747 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index 2f76a51d848..db6f470c863 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index 370b9a3caeb..6c0baf96aee 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index 72d6f7e6b8a..b7bcaf201a3 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index d585ace3003..d59d1b3b915 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index b77bfb94945..9e4930175f9 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index 289964a8b78..5c4478b27e6 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index d4766420f18..9d103defc96 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 7e447dc0f57..8ec7ff6f3ac 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26-SNAPSHOT + 9.3.26.v20190403 test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 From 5177abba6e736ba9155369731ee5acdb1282ec85 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 3 Apr 2019 14:10:43 +1100 Subject: [PATCH 32/74] close un-executed jobs on QueuedThreadPool lifecycle stop - new testcase in QueuedThreadPoolTest - added debug logs to QueuedThreadPool Signed-off-by: Lachlan Roberts --- .../jetty/util/thread/QueuedThreadPool.java | 35 +++++++- .../util/thread/QueuedThreadPoolTest.java | 84 +++++++++++++++++-- 2 files changed, 112 insertions(+), 7 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java index aa469ce3243..54ef1a6be45 100755 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java @@ -18,6 +18,7 @@ package org.eclipse.jetty.util.thread; +import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -146,6 +147,9 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP @Override protected void doStop() throws Exception { + if (LOG.isDebugEnabled()) + LOG.debug("Stopping {}", this); + removeBean(_tryExecutor); _tryExecutor = TryExecutor.NO_TRY; @@ -163,11 +167,13 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP for (int i = _threadsStarted.get(); i-- > 0; ) jobs.offer(noop); - // try to jobs complete naturally for half our stop time + // try to let jobs complete naturally for half our stop time long stopby = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeout) / 2; for (Thread thread : _threads) { long canwait = TimeUnit.NANOSECONDS.toMillis(stopby - System.nanoTime()); + if (LOG.isDebugEnabled()) + LOG.debug("Waiting for {} for {}", thread, canwait); if (canwait > 0) thread.join(canwait); } @@ -177,13 +183,19 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP // interrupt remaining threads if (_threadsStarted.get() > 0) for (Thread thread : _threads) + { + if (LOG.isDebugEnabled()) + LOG.debug("Interrupting {}", thread); thread.interrupt(); + } // wait again for the other half of our stop time stopby = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(timeout) / 2; for (Thread thread : _threads) { long canwait = TimeUnit.NANOSECONDS.toMillis(stopby - System.nanoTime()); + if (LOG.isDebugEnabled()) + LOG.debug("Waiting for {} for {}", thread, canwait); if (canwait > 0) thread.join(canwait); } @@ -213,6 +225,25 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP } } + // Close any un-executed jobs + while (!_jobs.isEmpty()) + { + Runnable job = _jobs.poll(); + if (job instanceof Closeable) + { + try + { + ((Closeable)job).close(); + } + catch (Throwable t) + { + LOG.warn(t); + } + } + else if (job != noop) + LOG.warn("Stopped without executing or closing {}", job); + } + if (_budget!=null) _budget.reset(); @@ -535,6 +566,8 @@ public class QueuedThreadPool extends ContainerLifeCycle implements SizedThreadP thread.setDaemon(isDaemon()); thread.setPriority(getThreadsPriority()); thread.setName(_name + "-" + thread.getId()); + if (LOG.isDebugEnabled()) + LOG.debug("Starting {}", thread); _threads.add(thread); _lastShrink.set(System.nanoTime()); thread.start(); diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java index c896a1dd2f2..ccf30c343ad 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java @@ -18,22 +18,30 @@ package org.eclipse.jetty.util.thread; -import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.util.thread.ThreadPool.SizedThreadPool; -import org.junit.jupiter.api.Test; - +import java.io.Closeable; +import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.util.thread.ThreadPool.SizedThreadPool; +import org.junit.jupiter.api.Test; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class QueuedThreadPoolTest extends AbstractThreadPoolTest { + private static final Logger LOG = Log.getLogger(QueuedThreadPoolTest.class); private final AtomicInteger _jobs=new AtomicInteger(); private class RunningJob implements Runnable @@ -41,6 +49,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest private final CountDownLatch _run = new CountDownLatch(1); private final CountDownLatch _stopping = new CountDownLatch(1); private final CountDownLatch _stopped = new CountDownLatch(1); + @Override public void run() { @@ -51,7 +60,7 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest } catch(Exception e) { - e.printStackTrace(); + LOG.debug(e); } finally { @@ -69,6 +78,17 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest } } + private class CloseableJob extends RunningJob implements Closeable + { + private final CountDownLatch _closed = new CountDownLatch(1); + + @Override + public void close() throws IOException + { + _closed.countDown(); + } + } + @Test public void testThreadPool() throws Exception { @@ -146,6 +166,58 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest waitForIdle(tp,2); } + @Test + public void testLifeCycleStop() throws Exception + { + QueuedThreadPool tp= new QueuedThreadPool(); + tp.setName("TestPool"); + tp.setMinThreads(1); + tp.setMaxThreads(2); + tp.setIdleTimeout(900); + tp.setStopTimeout(500); + tp.setThreadsPriority(Thread.NORM_PRIORITY-1); + tp.start(); + + // min threads started + waitForThreads(tp,1); + waitForIdle(tp,1); + + // Run job0 and job1 + RunningJob job0=new RunningJob(); + RunningJob job1=new RunningJob(); + tp.execute(job0); + tp.execute(job1); + + // Add a more jobs (which should not be run) + RunningJob job2=new RunningJob(); + CloseableJob job3=new CloseableJob(); + RunningJob job4=new RunningJob(); + tp.execute(job2); + tp.execute(job3); + tp.execute(job4); + + // Wait until the first 2 start running + waitForThreads(tp,2); + waitForIdle(tp,0); + + // Queue should be empty after thread pool is stopped + tp.stop(); + assertThat(tp.getQueue().size(), is(0)); + + // First 2 jobs closed by InterruptedException + assertThat(job0._stopped.await(200, TimeUnit.MILLISECONDS), is(true)); + assertThat(job1._stopped.await(200, TimeUnit.MILLISECONDS), is(true)); + + // Verify RunningJobs in the queue have not been run + assertThat(job2._run.await(200, TimeUnit.MILLISECONDS), is(false)); + assertThat(job4._run.await(200, TimeUnit.MILLISECONDS), is(false)); + + // Verify ClosableJobs have not been run but have been closed + assertThat(job4._run.await(200, TimeUnit.MILLISECONDS), is(false)); + assertThat(job3._closed.await(200, TimeUnit.MILLISECONDS), is(true)); + } + + @Test public void testShrink() throws Exception { From 5eed464730e934d889fc11c973be60c047eb17ef Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 3 Apr 2019 17:24:40 +1100 Subject: [PATCH 33/74] Issue #3382 - delay any frames received while suspended until resumed Signed-off-by: Lachlan Roberts --- .../eclipse/jetty/websocket/api/Session.java | 6 +--- .../common/JettyWebSocketFrameHandler.java | 30 ++++++++++++++++--- .../websocket/tests/SuspendResumeTest.java | 10 ++----- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java index 5c3e3a1a8a5..e5e7eecef3b 100644 --- a/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java +++ b/jetty-websocket/jetty-websocket-api/src/main/java/org/eclipse/jetty/websocket/api/Session.java @@ -164,11 +164,7 @@ public interface Session extends WebSocketPolicy, Closeable /** * Suspend the incoming read events on the connection. - *

- * This should be called during the processing of a frame or message to successfully - * suspend read events before the next frame is received. Calling suspend outside of - * this will only suspend read events after the next frame has been received. - *

+ * * @return the suspend token suitable for resuming the reading of data on the connection. */ SuspendToken suspend(); diff --git a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java index 979534e23c4..6e0382ba9ae 100644 --- a/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java +++ b/jetty-websocket/jetty-websocket-common/src/main/java/org/eclipse/jetty/websocket/common/JettyWebSocketFrameHandler.java @@ -80,6 +80,7 @@ public class JettyWebSocketFrameHandler implements FrameHandler private MessageSink activeMessageSink; private WebSocketSession session; private SuspendState state = SuspendState.DEMANDING; + private Callback suspendedCallback; public JettyWebSocketFrameHandler(WebSocketContainer container, Object endpointInstance, @@ -167,6 +168,24 @@ public class JettyWebSocketFrameHandler implements FrameHandler @Override public void onFrame(Frame frame, Callback callback) { + synchronized (this) + { + switch(state) + { + case DEMANDING: + break; + + case SUSPENDING: + suspendedCallback = Callback.from(()->onFrame(frame, callback)); + state = SuspendState.SUSPENDED; + return; + + case SUSPENDED: + default: + throw new IllegalStateException(); + } + } + // Send to raw frame handling on user side (eg: WebSocketFrameListener) if (frameHandle != null) { @@ -378,18 +397,18 @@ public class JettyWebSocketFrameHandler implements FrameHandler public void resume() { + Callback onFrame; synchronized (this) { + onFrame = suspendedCallback; + suspendedCallback = null; + switch(state) { case DEMANDING: throw new IllegalStateException("Already Resumed"); case SUSPENDED: - state = SuspendState.DEMANDING; - session.getCoreSession().demand(1); - break; - case SUSPENDING: state = SuspendState.DEMANDING; break; @@ -398,6 +417,9 @@ public class JettyWebSocketFrameHandler implements FrameHandler throw new IllegalStateException(); } } + + if (onFrame != null) + onFrame.succeeded(); } private void demand() diff --git a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java index 3b75c1b7a3f..8ffba97cc5e 100644 --- a/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java +++ b/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/SuspendResumeTest.java @@ -154,17 +154,13 @@ public class SuspendResumeTest clientSocket.session.getRemote().sendStringByFuture("message-from-client"); assertThat(serverSocket.messages.poll(5, TimeUnit.SECONDS), is("message-from-client")); - // the first message is received as we had already demanded before suspend - serverSocket.session.getRemote().sendStringByFuture("first-message"); - assertThat(clientSocket.messages.poll(5, TimeUnit.SECONDS), is("first-message")); - - // the second message is not received as it is suspended - serverSocket.session.getRemote().sendStringByFuture("second-message"); + // the message is not received as it is suspended + serverSocket.session.getRemote().sendStringByFuture("message-from-server"); assertNull(clientSocket.messages.poll(2, TimeUnit.SECONDS)); // client should receive message after it resumes suspendToken.resume(); - assertThat(clientSocket.messages.poll(5, TimeUnit.SECONDS), is("second-message")); + assertThat(clientSocket.messages.poll(5, TimeUnit.SECONDS), is("message-from-server")); // make sure both sides are closed clientSocket.session.close(); From 9f4b3542cb85b5c33c47aa2288822862176221be Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 3 Apr 2019 17:32:08 +1100 Subject: [PATCH 34/74] Updating to version 9.3.27-SNAPSHOT --- VERSION.txt | 2 + aggregates/jetty-all-compact3/pom.xml | 2 +- aggregates/jetty-all/pom.xml | 2 +- apache-jsp/pom.xml | 2 +- apache-jstl/pom.xml | 2 +- examples/async-rest/async-rest-jar/pom.xml | 2 +- examples/async-rest/async-rest-webapp/pom.xml | 2 +- examples/async-rest/pom.xml | 2 +- examples/embedded/pom.xml | 2 +- examples/pom.xml | 2 +- jetty-alpn/jetty-alpn-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-client/pom.xml | 2 +- jetty-alpn/jetty-alpn-java-server/pom.xml | 2 +- jetty-alpn/jetty-alpn-server/pom.xml | 2 +- jetty-alpn/pom.xml | 2 +- jetty-annotations/pom.xml | 2 +- jetty-ant/pom.xml | 2 +- jetty-bom/pom.xml | 72 +++++++++---------- jetty-cdi/cdi-core/pom.xml | 2 +- jetty-cdi/cdi-full-servlet/pom.xml | 2 +- jetty-cdi/cdi-servlet/pom.xml | 2 +- jetty-cdi/cdi-websocket/pom.xml | 2 +- jetty-cdi/pom.xml | 2 +- jetty-cdi/test-cdi-webapp/pom.xml | 2 +- jetty-client/pom.xml | 2 +- jetty-continuation/pom.xml | 2 +- jetty-deploy/pom.xml | 2 +- jetty-distribution/pom.xml | 2 +- jetty-documentation/pom.xml | 2 +- jetty-fcgi/fcgi-client/pom.xml | 2 +- jetty-fcgi/fcgi-server/pom.xml | 2 +- jetty-fcgi/pom.xml | 2 +- .../pom.xml | 2 +- .../jetty-gcloud-session-manager/pom.xml | 2 +- jetty-gcloud/pom.xml | 2 +- jetty-hazelcast/pom.xml | 2 +- jetty-http-spi/pom.xml | 2 +- jetty-http/pom.xml | 2 +- jetty-http2/http2-alpn-tests/pom.xml | 2 +- jetty-http2/http2-client/pom.xml | 2 +- jetty-http2/http2-common/pom.xml | 2 +- jetty-http2/http2-hpack/pom.xml | 2 +- .../http2-http-client-transport/pom.xml | 2 +- jetty-http2/http2-server/pom.xml | 2 +- jetty-http2/pom.xml | 2 +- jetty-infinispan/pom.xml | 2 +- jetty-io/pom.xml | 2 +- jetty-jaas/pom.xml | 2 +- jetty-jaspi/pom.xml | 2 +- jetty-jmx/pom.xml | 2 +- jetty-jndi/pom.xml | 2 +- jetty-jspc-maven-plugin/pom.xml | 2 +- jetty-maven-plugin/pom.xml | 2 +- jetty-monitor/pom.xml | 2 +- jetty-nosql/pom.xml | 2 +- jetty-osgi/jetty-osgi-alpn/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-jsp/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot-warurl/pom.xml | 2 +- jetty-osgi/jetty-osgi-boot/pom.xml | 2 +- jetty-osgi/jetty-osgi-httpservice/pom.xml | 2 +- jetty-osgi/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-context/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-fragment/pom.xml | 2 +- jetty-osgi/test-jetty-osgi-webapp/pom.xml | 2 +- jetty-osgi/test-jetty-osgi/pom.xml | 2 +- jetty-plus/pom.xml | 2 +- jetty-proxy/pom.xml | 2 +- jetty-quickstart/pom.xml | 2 +- jetty-rewrite/pom.xml | 2 +- jetty-runner/pom.xml | 2 +- jetty-security/pom.xml | 2 +- jetty-server/pom.xml | 2 +- jetty-servlet/pom.xml | 2 +- jetty-servlets/pom.xml | 2 +- jetty-spring/pom.xml | 2 +- jetty-start/pom.xml | 2 +- jetty-util-ajax/pom.xml | 2 +- jetty-util/pom.xml | 2 +- jetty-webapp/pom.xml | 2 +- .../javax-websocket-client-impl/pom.xml | 2 +- .../javax-websocket-server-impl/pom.xml | 2 +- jetty-websocket/pom.xml | 2 +- jetty-websocket/websocket-api/pom.xml | 2 +- jetty-websocket/websocket-client/pom.xml | 2 +- jetty-websocket/websocket-common/pom.xml | 2 +- jetty-websocket/websocket-server/pom.xml | 2 +- jetty-websocket/websocket-servlet/pom.xml | 2 +- jetty-xml/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- tests/test-continuation/pom.xml | 2 +- tests/test-http-client-transport/pom.xml | 2 +- tests/test-integration/pom.xml | 2 +- tests/test-jmx/jmx-webapp-it/pom.xml | 2 +- tests/test-jmx/jmx-webapp/pom.xml | 2 +- tests/test-jmx/pom.xml | 2 +- tests/test-loginservice/pom.xml | 2 +- tests/test-quickstart/pom.xml | 2 +- tests/test-sessions/pom.xml | 2 +- .../test-gcloud-memcached-sessions/pom.xml | 2 +- .../test-gcloud-sessions/pom.xml | 2 +- .../test-sessions/test-hash-sessions/pom.xml | 2 +- .../test-infinispan-sessions/pom.xml | 2 +- .../test-sessions/test-jdbc-sessions/pom.xml | 2 +- .../test-mongodb-sessions/pom.xml | 2 +- .../test-sessions-common/pom.xml | 2 +- tests/test-webapps/pom.xml | 2 +- tests/test-webapps/test-jaas-webapp/pom.xml | 2 +- tests/test-webapps/test-jetty-webapp/pom.xml | 2 +- tests/test-webapps/test-jndi-webapp/pom.xml | 2 +- .../test-webapps/test-mock-resources/pom.xml | 2 +- tests/test-webapps/test-proxy-webapp/pom.xml | 2 +- tests/test-webapps/test-servlet-spec/pom.xml | 2 +- .../test-container-initializer/pom.xml | 2 +- .../test-spec-webapp/pom.xml | 2 +- .../test-web-fragment/pom.xml | 2 +- .../test-webapps/test-webapp-rfc2616/pom.xml | 2 +- 117 files changed, 153 insertions(+), 151 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index ea67ac43e55..f7ca600044f 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,5 @@ +jetty-9.3.27-SNAPSHOT + jetty-9.3.26.v20190403 - 03 April 2019 + 3487 Test WebAppClassLoader does not definePackage + 3461 gzip request customizer diff --git a/aggregates/jetty-all-compact3/pom.xml b/aggregates/jetty-all-compact3/pom.xml index d49ac19e77c..094f802b0eb 100644 --- a/aggregates/jetty-all-compact3/pom.xml +++ b/aggregates/jetty-all-compact3/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index 1c0f8c63e21..7c47fbb5027 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/apache-jsp/pom.xml b/apache-jsp/pom.xml index f8b383f190d..a3f21300309 100644 --- a/apache-jsp/pom.xml +++ b/apache-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 apache-jsp diff --git a/apache-jstl/pom.xml b/apache-jstl/pom.xml index a533edbf4fb..aedff09ae43 100644 --- a/apache-jstl/pom.xml +++ b/apache-jstl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 apache-jstl diff --git a/examples/async-rest/async-rest-jar/pom.xml b/examples/async-rest/async-rest-jar/pom.xml index 2474ee20b0c..a80fdf9ffdd 100644 --- a/examples/async-rest/async-rest-jar/pom.xml +++ b/examples/async-rest/async-rest-jar/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/async-rest-webapp/pom.xml b/examples/async-rest/async-rest-webapp/pom.xml index 6cc9ecbc39e..26b21560ed5 100644 --- a/examples/async-rest/async-rest-webapp/pom.xml +++ b/examples/async-rest/async-rest-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty example-async-rest - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 org.eclipse.jetty.example-async-rest diff --git a/examples/async-rest/pom.xml b/examples/async-rest/pom.xml index 12a3da57f6f..371c7d845c5 100644 --- a/examples/async-rest/pom.xml +++ b/examples/async-rest/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml index aa77c6f06fe..48591a026b3 100644 --- a/examples/embedded/pom.xml +++ b/examples/embedded/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.examples examples-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 0e054c1f0e5..c8a7ee70823 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml org.eclipse.jetty.examples diff --git a/jetty-alpn/jetty-alpn-client/pom.xml b/jetty-alpn/jetty-alpn-client/pom.xml index edfd9961600..7c55cc7df50 100644 --- a/jetty-alpn/jetty-alpn-client/pom.xml +++ b/jetty-alpn/jetty-alpn-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-alpn-client diff --git a/jetty-alpn/jetty-alpn-java-client/pom.xml b/jetty-alpn/jetty-alpn-java-client/pom.xml index cbae050494f..de1852061cb 100644 --- a/jetty-alpn/jetty-alpn-java-client/pom.xml +++ b/jetty-alpn/jetty-alpn-java-client/pom.xml @@ -6,7 +6,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-java-server/pom.xml b/jetty-alpn/jetty-alpn-java-server/pom.xml index ba71797935e..e64ce1742bf 100644 --- a/jetty-alpn/jetty-alpn-java-server/pom.xml +++ b/jetty-alpn/jetty-alpn-java-server/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-alpn/jetty-alpn-server/pom.xml b/jetty-alpn/jetty-alpn-server/pom.xml index 0bcae5db4c1..e778792d609 100644 --- a/jetty-alpn/jetty-alpn-server/pom.xml +++ b/jetty-alpn/jetty-alpn-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-alpn-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-alpn-server diff --git a/jetty-alpn/pom.xml b/jetty-alpn/pom.xml index 2d280537320..cc689ac4b5b 100644 --- a/jetty-alpn/pom.xml +++ b/jetty-alpn/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-alpn-parent diff --git a/jetty-annotations/pom.xml b/jetty-annotations/pom.xml index e17a72c9eab..9a616471202 100644 --- a/jetty-annotations/pom.xml +++ b/jetty-annotations/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-annotations diff --git a/jetty-ant/pom.xml b/jetty-ant/pom.xml index 8b550690679..b71cd08a91d 100644 --- a/jetty-ant/pom.xml +++ b/jetty-ant/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-ant diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index a907be62083..122a16c603d 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -98,7 +98,7 @@ org.eclipse.jetty jetty-annotations - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -118,22 +118,22 @@ org.eclipse.jetty jetty-client - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-continuation - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.fcgi fcgi-server - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.fcgi fcgi-server - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -148,82 +148,82 @@ org.eclipse.jetty jetty-hazelcast - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-http - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.http2 http2-client - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.http2 http2-common - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.http2 http2-hpack - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.http2 http2-http-client-transport - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty.http2 http2-server - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-http-spi - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-infinispan - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-io - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-jaas - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-jaspi - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-jmx - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-jndi - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-monitor - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-nosql - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -243,62 +243,62 @@ org.eclipse.jetty jetty-plus - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-proxy - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-quickstart - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-rewrite - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-security - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-server - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-servlet - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-servlets - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-spring - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-util - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-util-ajax - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-webapp - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -338,18 +338,18 @@ org.eclipse.jetty jetty-xml - 9.3.26.v20190403 + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-distribution - 9.3.26.v20190403 + 9.3.27-SNAPSHOT zip org.eclipse.jetty jetty-distribution - 9.3.26.v20190403 + 9.3.27-SNAPSHOT tar.gz diff --git a/jetty-cdi/cdi-core/pom.xml b/jetty-cdi/cdi-core/pom.xml index 71fa6a6277c..f97e9363ed9 100644 --- a/jetty-cdi/cdi-core/pom.xml +++ b/jetty-cdi/cdi-core/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 cdi-core diff --git a/jetty-cdi/cdi-full-servlet/pom.xml b/jetty-cdi/cdi-full-servlet/pom.xml index 85eb2163265..7f17a12e275 100644 --- a/jetty-cdi/cdi-full-servlet/pom.xml +++ b/jetty-cdi/cdi-full-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 cdi-full-servlet diff --git a/jetty-cdi/cdi-servlet/pom.xml b/jetty-cdi/cdi-servlet/pom.xml index 10696134004..f554336d962 100644 --- a/jetty-cdi/cdi-servlet/pom.xml +++ b/jetty-cdi/cdi-servlet/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 cdi-servlet diff --git a/jetty-cdi/cdi-websocket/pom.xml b/jetty-cdi/cdi-websocket/pom.xml index 8e8cdd3eb0d..8ea4fbb789b 100644 --- a/jetty-cdi/cdi-websocket/pom.xml +++ b/jetty-cdi/cdi-websocket/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 cdi-websocket diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index 4224355a292..4182a364443 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 org.eclipse.jetty.cdi diff --git a/jetty-cdi/test-cdi-webapp/pom.xml b/jetty-cdi/test-cdi-webapp/pom.xml index 473220a3043..141b91d24da 100644 --- a/jetty-cdi/test-cdi-webapp/pom.xml +++ b/jetty-cdi/test-cdi-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.cdi jetty-cdi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 test-cdi-webapp diff --git a/jetty-client/pom.xml b/jetty-client/pom.xml index a397e39d45e..9308c2f5720 100644 --- a/jetty-client/pom.xml +++ b/jetty-client/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-continuation/pom.xml b/jetty-continuation/pom.xml index 83a5e353182..8065465a0c5 100644 --- a/jetty-continuation/pom.xml +++ b/jetty-continuation/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-continuation diff --git a/jetty-deploy/pom.xml b/jetty-deploy/pom.xml index 056d6f44752..11cee503d2c 100644 --- a/jetty-deploy/pom.xml +++ b/jetty-deploy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-deploy diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 352c0784644..fab75d5c756 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-distribution diff --git a/jetty-documentation/pom.xml b/jetty-documentation/pom.xml index f5ab74d8ff4..45d15c09719 100644 --- a/jetty-documentation/pom.xml +++ b/jetty-documentation/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT jetty-documentation Jetty :: Documentation diff --git a/jetty-fcgi/fcgi-client/pom.xml b/jetty-fcgi/fcgi-client/pom.xml index bbbca428645..a7ba63ea980 100644 --- a/jetty-fcgi/fcgi-client/pom.xml +++ b/jetty-fcgi/fcgi-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/fcgi-server/pom.xml b/jetty-fcgi/fcgi-server/pom.xml index a1126e74d6c..0b6fe0a6641 100644 --- a/jetty-fcgi/fcgi-server/pom.xml +++ b/jetty-fcgi/fcgi-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.fcgi fcgi-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-fcgi/pom.xml b/jetty-fcgi/pom.xml index 79f96141d83..51ddc094e5a 100644 --- a/jetty-fcgi/pom.xml +++ b/jetty-fcgi/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml index 42924d02166..5c868c6a3a3 100644 --- a/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-memcached-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml index f87cbfa7f34..fb40beebc0c 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/pom.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.gcloud gcloud-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-gcloud/pom.xml b/jetty-gcloud/pom.xml index 5e54e3f7cf0..121dc052a4c 100644 --- a/jetty-gcloud/pom.xml +++ b/jetty-gcloud/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index f5f11225fee..5807e4fb559 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-hazelcast diff --git a/jetty-http-spi/pom.xml b/jetty-http-spi/pom.xml index f0fa86d0069..cdf4f949289 100644 --- a/jetty-http-spi/pom.xml +++ b/jetty-http-spi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-http-spi diff --git a/jetty-http/pom.xml b/jetty-http/pom.xml index 538886ec529..f40d43438cd 100644 --- a/jetty-http/pom.xml +++ b/jetty-http/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-http diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml index 2fddae32661..878fadbaf18 100644 --- a/jetty-http2/http2-alpn-tests/pom.xml +++ b/jetty-http2/http2-alpn-tests/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-client/pom.xml b/jetty-http2/http2-client/pom.xml index 85d973564f9..f90005e0a0d 100644 --- a/jetty-http2/http2-client/pom.xml +++ b/jetty-http2/http2-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-common/pom.xml b/jetty-http2/http2-common/pom.xml index 824ab8f9d97..90a94cbb1ed 100644 --- a/jetty-http2/http2-common/pom.xml +++ b/jetty-http2/http2-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-hpack/pom.xml b/jetty-http2/http2-hpack/pom.xml index 9e3b62acb0b..76b0c87988f 100644 --- a/jetty-http2/http2-hpack/pom.xml +++ b/jetty-http2/http2-hpack/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-http-client-transport/pom.xml b/jetty-http2/http2-http-client-transport/pom.xml index 5335defcd4b..08d6f4a139a 100644 --- a/jetty-http2/http2-http-client-transport/pom.xml +++ b/jetty-http2/http2-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 30abe5f4903..7e69398ae08 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.http2 http2-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml index 6dc56079f83..a306f1a878e 100644 --- a/jetty-http2/pom.xml +++ b/jetty-http2/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-infinispan/pom.xml b/jetty-infinispan/pom.xml index 8124a531103..2065504f8ac 100644 --- a/jetty-infinispan/pom.xml +++ b/jetty-infinispan/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-infinispan diff --git a/jetty-io/pom.xml b/jetty-io/pom.xml index efc6c06577b..d6d40294438 100644 --- a/jetty-io/pom.xml +++ b/jetty-io/pom.xml @@ -2,7 +2,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-io diff --git a/jetty-jaas/pom.xml b/jetty-jaas/pom.xml index ce51ed0ac42..8b0cb3c9820 100644 --- a/jetty-jaas/pom.xml +++ b/jetty-jaas/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-jaas diff --git a/jetty-jaspi/pom.xml b/jetty-jaspi/pom.xml index 07ae7f4d694..e4f3520b66b 100644 --- a/jetty-jaspi/pom.xml +++ b/jetty-jaspi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-jaspi diff --git a/jetty-jmx/pom.xml b/jetty-jmx/pom.xml index e39d7ade2de..2ae8a9efaff 100644 --- a/jetty-jmx/pom.xml +++ b/jetty-jmx/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-jmx diff --git a/jetty-jndi/pom.xml b/jetty-jndi/pom.xml index b7c3072ca26..edce7857f83 100644 --- a/jetty-jndi/pom.xml +++ b/jetty-jndi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-jndi diff --git a/jetty-jspc-maven-plugin/pom.xml b/jetty-jspc-maven-plugin/pom.xml index 529c769c84b..810c1cbce59 100644 --- a/jetty-jspc-maven-plugin/pom.xml +++ b/jetty-jspc-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-jspc-maven-plugin diff --git a/jetty-maven-plugin/pom.xml b/jetty-maven-plugin/pom.xml index 75ee56efe6b..c1c4dbf2b73 100644 --- a/jetty-maven-plugin/pom.xml +++ b/jetty-maven-plugin/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-maven-plugin diff --git a/jetty-monitor/pom.xml b/jetty-monitor/pom.xml index 53dda3b180d..f5a9b241e0d 100644 --- a/jetty-monitor/pom.xml +++ b/jetty-monitor/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-monitor diff --git a/jetty-nosql/pom.xml b/jetty-nosql/pom.xml index 7e822e7319f..cb7e089942c 100644 --- a/jetty-nosql/pom.xml +++ b/jetty-nosql/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-nosql diff --git a/jetty-osgi/jetty-osgi-alpn/pom.xml b/jetty-osgi/jetty-osgi-alpn/pom.xml index bf63f6fe3c1..cf350f4c1ba 100644 --- a/jetty-osgi/jetty-osgi-alpn/pom.xml +++ b/jetty-osgi/jetty-osgi-alpn/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-osgi-alpn diff --git a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml index 5c0f67ee286..4f97952016d 100644 --- a/jetty-osgi/jetty-osgi-boot-jsp/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-jsp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-osgi-boot-jsp diff --git a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml index 027b9615a0b..50580fded3b 100644 --- a/jetty-osgi/jetty-osgi-boot-warurl/pom.xml +++ b/jetty-osgi/jetty-osgi-boot-warurl/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/jetty-osgi-boot/pom.xml b/jetty-osgi/jetty-osgi-boot/pom.xml index f94eb9d7526..d585da29b17 100644 --- a/jetty-osgi/jetty-osgi-boot/pom.xml +++ b/jetty-osgi/jetty-osgi-boot/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-osgi-boot diff --git a/jetty-osgi/jetty-osgi-httpservice/pom.xml b/jetty-osgi/jetty-osgi-httpservice/pom.xml index 55118a74df8..ca8173f6231 100644 --- a/jetty-osgi/jetty-osgi-httpservice/pom.xml +++ b/jetty-osgi/jetty-osgi-httpservice/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-httpservice diff --git a/jetty-osgi/pom.xml b/jetty-osgi/pom.xml index d13121a9905..ee6ccf2a3d8 100644 --- a/jetty-osgi/pom.xml +++ b/jetty-osgi/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-context/pom.xml b/jetty-osgi/test-jetty-osgi-context/pom.xml index 2f39bca9c36..7f1a2ea9c0d 100644 --- a/jetty-osgi/test-jetty-osgi-context/pom.xml +++ b/jetty-osgi/test-jetty-osgi-context/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 test-jetty-osgi-context diff --git a/jetty-osgi/test-jetty-osgi-fragment/pom.xml b/jetty-osgi/test-jetty-osgi-fragment/pom.xml index 5750951106f..3abe0ac6823 100644 --- a/jetty-osgi/test-jetty-osgi-fragment/pom.xml +++ b/jetty-osgi/test-jetty-osgi-fragment/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi-webapp/pom.xml b/jetty-osgi/test-jetty-osgi-webapp/pom.xml index b6fa8190b36..746b39318de 100644 --- a/jetty-osgi/test-jetty-osgi-webapp/pom.xml +++ b/jetty-osgi/test-jetty-osgi-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 8eafe3f1062..c015a37bfd1 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.osgi jetty-osgi-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/jetty-plus/pom.xml b/jetty-plus/pom.xml index b5063dd108a..568f07b288a 100644 --- a/jetty-plus/pom.xml +++ b/jetty-plus/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-plus diff --git a/jetty-proxy/pom.xml b/jetty-proxy/pom.xml index dc7848f0d86..f5f553f004d 100644 --- a/jetty-proxy/pom.xml +++ b/jetty-proxy/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-proxy diff --git a/jetty-quickstart/pom.xml b/jetty-quickstart/pom.xml index 59929de5dc1..85aa76992bb 100644 --- a/jetty-quickstart/pom.xml +++ b/jetty-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 org.eclipse.jetty diff --git a/jetty-rewrite/pom.xml b/jetty-rewrite/pom.xml index 919d013047d..fae706086a4 100644 --- a/jetty-rewrite/pom.xml +++ b/jetty-rewrite/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-rewrite diff --git a/jetty-runner/pom.xml b/jetty-runner/pom.xml index d49f5b2bba5..7f0a4a11dbc 100644 --- a/jetty-runner/pom.xml +++ b/jetty-runner/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-runner diff --git a/jetty-security/pom.xml b/jetty-security/pom.xml index 958b32e36b4..583c4c4a6d7 100644 --- a/jetty-security/pom.xml +++ b/jetty-security/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-security diff --git a/jetty-server/pom.xml b/jetty-server/pom.xml index 69cabcdd8e4..e78a8dbf059 100644 --- a/jetty-server/pom.xml +++ b/jetty-server/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-server diff --git a/jetty-servlet/pom.xml b/jetty-servlet/pom.xml index e52e6ede6be..1b444b2eb4c 100644 --- a/jetty-servlet/pom.xml +++ b/jetty-servlet/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-servlet diff --git a/jetty-servlets/pom.xml b/jetty-servlets/pom.xml index 62a2b549545..10e57c0a296 100644 --- a/jetty-servlets/pom.xml +++ b/jetty-servlets/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-servlets diff --git a/jetty-spring/pom.xml b/jetty-spring/pom.xml index 6871a291c18..7fee27aa875 100644 --- a/jetty-spring/pom.xml +++ b/jetty-spring/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-spring diff --git a/jetty-start/pom.xml b/jetty-start/pom.xml index ad8c5223e4a..617367efc2e 100644 --- a/jetty-start/pom.xml +++ b/jetty-start/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-start diff --git a/jetty-util-ajax/pom.xml b/jetty-util-ajax/pom.xml index 2db83000884..a689b5556fc 100644 --- a/jetty-util-ajax/pom.xml +++ b/jetty-util-ajax/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-util-ajax diff --git a/jetty-util/pom.xml b/jetty-util/pom.xml index 0b46d983460..7d9d246c4d2 100644 --- a/jetty-util/pom.xml +++ b/jetty-util/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-util diff --git a/jetty-webapp/pom.xml b/jetty-webapp/pom.xml index 3050838902d..99e3484e14f 100644 --- a/jetty-webapp/pom.xml +++ b/jetty-webapp/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-webapp diff --git a/jetty-websocket/javax-websocket-client-impl/pom.xml b/jetty-websocket/javax-websocket-client-impl/pom.xml index c0550138c2e..78034bb65c1 100644 --- a/jetty-websocket/javax-websocket-client-impl/pom.xml +++ b/jetty-websocket/javax-websocket-client-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/javax-websocket-server-impl/pom.xml b/jetty-websocket/javax-websocket-server-impl/pom.xml index 3be3be597ac..fd1f3ea245a 100644 --- a/jetty-websocket/javax-websocket-server-impl/pom.xml +++ b/jetty-websocket/javax-websocket-server-impl/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/pom.xml b/jetty-websocket/pom.xml index 9956e4bb2da..a72dd06084a 100644 --- a/jetty-websocket/pom.xml +++ b/jetty-websocket/pom.xml @@ -3,7 +3,7 @@ jetty-project org.eclipse.jetty - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-api/pom.xml b/jetty-websocket/websocket-api/pom.xml index add02af9d0a..19ca3e6a719 100644 --- a/jetty-websocket/websocket-api/pom.xml +++ b/jetty-websocket/websocket-api/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-client/pom.xml b/jetty-websocket/websocket-client/pom.xml index a85a8e98054..e80ff8a6374 100644 --- a/jetty-websocket/websocket-client/pom.xml +++ b/jetty-websocket/websocket-client/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-common/pom.xml b/jetty-websocket/websocket-common/pom.xml index 7434fcdaf4c..67d69ccccc7 100644 --- a/jetty-websocket/websocket-common/pom.xml +++ b/jetty-websocket/websocket-common/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-server/pom.xml b/jetty-websocket/websocket-server/pom.xml index d01b680cf8d..3dc35015b9e 100644 --- a/jetty-websocket/websocket-server/pom.xml +++ b/jetty-websocket/websocket-server/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-websocket/websocket-servlet/pom.xml b/jetty-websocket/websocket-servlet/pom.xml index 193ea425da9..1ad87f642c4 100644 --- a/jetty-websocket/websocket-servlet/pom.xml +++ b/jetty-websocket/websocket-servlet/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.websocket websocket-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/jetty-xml/pom.xml b/jetty-xml/pom.xml index 655d3188952..7eb5bbfbeb3 100644 --- a/jetty-xml/pom.xml +++ b/jetty-xml/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jetty-xml diff --git a/pom.xml b/pom.xml index 6be76865fed..fca0aeb4c45 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT Jetty :: Project http://www.eclipse.org/jetty pom diff --git a/tests/pom.xml b/tests/pom.xml index 6340c266dc1..208e7fc872b 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml org.eclipse.jetty.tests diff --git a/tests/test-continuation/pom.xml b/tests/test-continuation/pom.xml index 6d8c71ed8a3..e6333976800 100644 --- a/tests/test-continuation/pom.xml +++ b/tests/test-continuation/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-http-client-transport/pom.xml b/tests/test-http-client-transport/pom.xml index 18e788bcbdb..3654831803c 100644 --- a/tests/test-http-client-transport/pom.xml +++ b/tests/test-http-client-transport/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 diff --git a/tests/test-integration/pom.xml b/tests/test-integration/pom.xml index 44eab34eca4..403e399dca6 100644 --- a/tests/test-integration/pom.xml +++ b/tests/test-integration/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 test-integration diff --git a/tests/test-jmx/jmx-webapp-it/pom.xml b/tests/test-jmx/jmx-webapp-it/pom.xml index d4a4d2e88df..a68deea3969 100644 --- a/tests/test-jmx/jmx-webapp-it/pom.xml +++ b/tests/test-jmx/jmx-webapp-it/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 jmx-webapp-it diff --git a/tests/test-jmx/jmx-webapp/pom.xml b/tests/test-jmx/jmx-webapp/pom.xml index a35f2c246d1..8f1a38d3b7a 100644 --- a/tests/test-jmx/jmx-webapp/pom.xml +++ b/tests/test-jmx/jmx-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-jmx-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT jmx-webapp war diff --git a/tests/test-jmx/pom.xml b/tests/test-jmx/pom.xml index b6fcc5e7f79..8bf1be41bb6 100644 --- a/tests/test-jmx/pom.xml +++ b/tests/test-jmx/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT 4.0.0 test-jmx-parent diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml index c2ccf6d6f24..db96814c816 100644 --- a/tests/test-loginservice/pom.xml +++ b/tests/test-loginservice/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-loginservice Jetty Tests :: Login Service diff --git a/tests/test-quickstart/pom.xml b/tests/test-quickstart/pom.xml index 3c942f5d075..14763f89e02 100644 --- a/tests/test-quickstart/pom.xml +++ b/tests/test-quickstart/pom.xml @@ -2,7 +2,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 03d1005babc..e5442d997e9 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-sessions-parent Jetty Tests :: Sessions :: Parent diff --git a/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml b/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml index eae51cb58ae..a729f7131d1 100644 --- a/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-memcached-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-gcloud-memcached-sessions Jetty Tests :: Sessions :: GCloud with Memcached diff --git a/tests/test-sessions/test-gcloud-sessions/pom.xml b/tests/test-sessions/test-gcloud-sessions/pom.xml index c142c92c8fd..ee16848ca97 100644 --- a/tests/test-sessions/test-gcloud-sessions/pom.xml +++ b/tests/test-sessions/test-gcloud-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-gcloud-sessions Jetty Tests :: Sessions :: GCloud diff --git a/tests/test-sessions/test-hash-sessions/pom.xml b/tests/test-sessions/test-hash-sessions/pom.xml index 69a628787fb..4e6117be70f 100644 --- a/tests/test-sessions/test-hash-sessions/pom.xml +++ b/tests/test-sessions/test-hash-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-hash-sessions Jetty Tests :: Sessions :: Hash diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index 42442a5a071..ad026a3aa97 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-infinispan-sessions Jetty Tests :: Sessions :: Infinispan diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml index d467788899c..392feedd9db 100644 --- a/tests/test-sessions/test-jdbc-sessions/pom.xml +++ b/tests/test-sessions/test-jdbc-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-jdbc-sessions Jetty Tests :: Sessions :: JDBC diff --git a/tests/test-sessions/test-mongodb-sessions/pom.xml b/tests/test-sessions/test-mongodb-sessions/pom.xml index b71442b3e2d..38a57762dd6 100644 --- a/tests/test-sessions/test-mongodb-sessions/pom.xml +++ b/tests/test-sessions/test-mongodb-sessions/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-mongodb-sessions Jetty Tests :: Sessions :: Mongo diff --git a/tests/test-sessions/test-sessions-common/pom.xml b/tests/test-sessions/test-sessions-common/pom.xml index 91406768f51..14e6067e1f9 100644 --- a/tests/test-sessions/test-sessions-common/pom.xml +++ b/tests/test-sessions/test-sessions-common/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-sessions-common Jetty Tests :: Sessions :: Common diff --git a/tests/test-webapps/pom.xml b/tests/test-webapps/pom.xml index 010fa50b4e3..56e4ac9e788 100644 --- a/tests/test-webapps/pom.xml +++ b/tests/test-webapps/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests tests-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml test-webapps-parent diff --git a/tests/test-webapps/test-jaas-webapp/pom.xml b/tests/test-webapps/test-jaas-webapp/pom.xml index 36e0aec91ea..14bbcdfeb42 100644 --- a/tests/test-webapps/test-jaas-webapp/pom.xml +++ b/tests/test-webapps/test-jaas-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-jaas-webapp Jetty Tests :: WebApp :: JAAS diff --git a/tests/test-webapps/test-jetty-webapp/pom.xml b/tests/test-webapps/test-jetty-webapp/pom.xml index cd991e41747..841f7374747 100644 --- a/tests/test-webapps/test-jetty-webapp/pom.xml +++ b/tests/test-webapps/test-jetty-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-jndi-webapp/pom.xml b/tests/test-webapps/test-jndi-webapp/pom.xml index db6f470c863..91e7ca83f7d 100644 --- a/tests/test-webapps/test-jndi-webapp/pom.xml +++ b/tests/test-webapps/test-jndi-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-jndi-webapp Jetty Tests :: WebApp :: JNDI diff --git a/tests/test-webapps/test-mock-resources/pom.xml b/tests/test-webapps/test-mock-resources/pom.xml index 6c0baf96aee..11df973303d 100644 --- a/tests/test-webapps/test-mock-resources/pom.xml +++ b/tests/test-webapps/test-mock-resources/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT Jetty Tests :: WebApp :: Mock Resources test-mock-resources diff --git a/tests/test-webapps/test-proxy-webapp/pom.xml b/tests/test-webapps/test-proxy-webapp/pom.xml index b7bcaf201a3..16ba25197ed 100644 --- a/tests/test-webapps/test-proxy-webapp/pom.xml +++ b/tests/test-webapps/test-proxy-webapp/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT ../pom.xml 4.0.0 diff --git a/tests/test-webapps/test-servlet-spec/pom.xml b/tests/test-webapps/test-servlet-spec/pom.xml index d59d1b3b915..9e908984508 100644 --- a/tests/test-webapps/test-servlet-spec/pom.xml +++ b/tests/test-webapps/test-servlet-spec/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-servlet-spec-parent Jetty Tests :: Spec Test WebApp :: Parent diff --git a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml index 9e4930175f9..27622a8a22a 100644 --- a/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-container-initializer/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-container-initializer jar diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml index 5c4478b27e6..98f55ec5a6c 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT Jetty Tests :: Webapps :: Spec Webapp test-spec-webapp diff --git a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml index 9d103defc96..0a3b276c719 100644 --- a/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml +++ b/tests/test-webapps/test-servlet-spec/test-web-fragment/pom.xml @@ -3,7 +3,7 @@ org.eclipse.jetty.tests test-servlet-spec-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT Jetty Tests :: WebApp :: Servlet Spec :: Fragment Jar diff --git a/tests/test-webapps/test-webapp-rfc2616/pom.xml b/tests/test-webapps/test-webapp-rfc2616/pom.xml index 8ec7ff6f3ac..16eca1dde17 100644 --- a/tests/test-webapps/test-webapp-rfc2616/pom.xml +++ b/tests/test-webapps/test-webapp-rfc2616/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty.tests test-webapps-parent - 9.3.26.v20190403 + 9.3.27-SNAPSHOT test-webapp-rfc2616 Jetty Tests :: WebApp :: RFC2616 From c0c29963392f51342b30b0065e5793812de00630 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 3 Apr 2019 18:18:48 +1100 Subject: [PATCH 35/74] fixed annotationtest Signed-off-by: Greg Wilkins --- .../src/main/java/com/acme/test/AnnotationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java index f28e04f8a64..ceb14e049ca 100644 --- a/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java +++ b/tests/test-webapps/test-servlet-spec/test-spec-webapp/src/main/java/com/acme/test/AnnotationTest.java @@ -206,10 +206,10 @@ public class AnnotationTest extends HttpServlet boolean fragInitParamResult = "123".equals(config.getInitParameter("extra1")) && "345".equals(config.getInitParameter("extra2")); out.println("

Result: "+(fragInitParamResult? "PASS": "FAIL")+"

"); - __HandlesTypes = Arrays.asList( "javax.servlet.GenericServlet", "javax.servlet.http.HttpServlet", "com.acme.test.AsyncListenerServlet", + "com.acme.test.ClassLoaderServlet", "com.acme.test.AnnotationTest", "com.acme.test.RoleAnnotationTest", "com.acme.test.MultiPartTest", From 6051d135f281bc5ab08610a829fcaac5846a3e16 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 3 Apr 2019 17:31:25 +1000 Subject: [PATCH 36/74] fix version in pom and use trick from 9.4.x branch with flatten-maven-plugin Signed-off-by: olivier lamy --- jetty-bom/pom.xml | 151 ++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 98 deletions(-) diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 122a16c603d..bbc0e29ffc5 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -1,96 +1,51 @@ - - org.eclipse.jetty - jetty-parent - 25 - 4.0.0 jetty-bom - 9.3.26.v20190403 Jetty :: Bom Jetty BOM artifact http://www.eclipse.org/jetty - 1995 pom - - github - https://github.com/eclipse/jetty.project/issues - - - - - Apache Software License - Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0 - - - Eclipse Public License - Version 1.0 - http://www.eclipse.org/org/documents/epl-v10.php - - - - - http://www.eclipse.org/jetty - UTF-8 - 1.4 - - - - scm:git:https://github.com/eclipse/jetty.project.git - scm:git:git@github.com:eclipse/jetty.project.git - https://github.com/eclipse/jetty.project - - - - - oss.sonatype.org - Jetty Staging Repository - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - oss.sonatype.org - Jetty Snapshot Repository - https://oss.sonatype.org/content/repositories/jetty-snapshots/ - - - jetty.eclipse.website - scp://build.eclipse.org:/home/data/httpd/download.eclipse.org/jetty/${project.version}/ - - + + org.eclipse.jetty + jetty-project + 9.3.27-SNAPSHOT + - - - - org.apache.maven.plugins - maven-release-plugin - 2.5 - - false - deploy - -Peclipse-release - clean install - forked-path - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - true - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.0.0-M1 - - true - - - - + + + org.codehaus.mojo + flatten-maven-plugin + 1.0.1 + + ${project.build.directory} + flattened-pom.xml + bom + true + + remove + remove + + + + + flatten + + flatten + + process-resources + + + flatten-clean + + clean + + clean + + + + @@ -103,17 +58,17 @@ org.eclipse.jetty cdi-core - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty cdi-servlet - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty cdi-websocket - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -138,12 +93,12 @@ org.eclipse.jetty jetty-gcloud-memcached-session-manager - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-gcloud-session-manager - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -228,17 +183,17 @@ org.eclipse.jetty jetty-osgi-boot - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-osgi-boot-jsp - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty jetty-osgi-boot-warurl - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty @@ -303,37 +258,37 @@ org.eclipse.jetty javax-websocket-client-impl - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty javax-websocket-server-impl - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty javax-websocket-api - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty javax-websocket-client - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty javax-websocket-common - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty javax-websocket-server - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty javax-websocket-servlet - 9.3.26-SNAPSHOT + 9.3.27-SNAPSHOT org.eclipse.jetty From b9b1ade5daa0b926c252af29fab5664ba39a8402 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Wed, 3 Apr 2019 18:08:07 +1000 Subject: [PATCH 37/74] Jetty 9.3.x same jenkinsfile as 9.4.x (#3522) * use same Jenkinsfile as 9.4.x Signed-off-by: olivier lamy * use only jdk8 even for javadoc Signed-off-by: olivier lamy --- Jenkinsfile | 227 ++++++++++++++++++---------------------------------- 1 file changed, 77 insertions(+), 150 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6d98a5333cc..1eb73441ed8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,165 +1,92 @@ #!groovy -node { - // System Dependent Locations - def mvntool = tool name: 'maven3', type: 'hudson.tasks.Maven$MavenInstallation' - def jdktool = tool name: 'jdk8', type: 'hudson.model.JDK' +pipeline { + agent any + // save some io during the build + options { durabilityHint('PERFORMANCE_OPTIMIZED') } + stages { + stage("Parallel Stage") { + parallel { + stage("Build / Test - JDK8") { + agent { node { label 'linux' } } + options { timeout(time: 120, unit: 'MINUTES') } + steps { + mavenBuild("jdk8", "-Pmongodb install", "maven3", false) + // Collect up the jacoco execution results (only on main build) + jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class', + exclusionPattern: '' + + // build tools + '**/org/eclipse/jetty/ant/**' + + ',**/org/eclipse/jetty/maven/**' + + ',**/org/eclipse/jetty/jspc/**' + + // example code / documentation + ',**/org/eclipse/jetty/embedded/**' + + ',**/org/eclipse/jetty/asyncrest/**' + + ',**/org/eclipse/jetty/demo/**' + + // special environments / late integrations + ',**/org/eclipse/jetty/gcloud/**' + + ',**/org/eclipse/jetty/infinispan/**' + + ',**/org/eclipse/jetty/osgi/**' + + ',**/org/eclipse/jetty/spring/**' + + ',**/org/eclipse/jetty/http/spi/**' + + // test classes + ',**/org/eclipse/jetty/tests/**' + + ',**/org/eclipse/jetty/test/**', + execPattern: '**/target/jacoco.exec', + classPattern: '**/target/classes', + sourcePattern: '**/src/main/java' + warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']] + maven_invoker reportsFilenamePattern: "**/target/invoker-reports/BUILD*.xml", invokerBuildDir: "**/target/it" + } + } - // Environment - List mvnEnv = ["PATH+MVN=${mvntool}/bin", "PATH+JDK=${jdktool}/bin", "JAVA_HOME=${jdktool}/", "MAVEN_HOME=${mvntool}"] - mvnEnv.add("MAVEN_OPTS=-Xms256m -Xmx1024m -Djava.awt.headless=true") + stage("Build Javadoc") { + agent { node { label 'linux' } } + options { timeout(time: 30, unit: 'MINUTES') } + steps { + mavenBuild("jdk8", "install javadoc:javadoc -DskipTests", "maven3", true) + warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'JavaDoc'], [parserName: 'Java']] + } + } - try - { - stage('Checkout') { - checkout scm - } - } catch (Exception e) { - notifyBuild("Checkout Failure") - throw e - } - - try - { - stage('Compile') { - withEnv(mvnEnv) { - timeout(time: 15, unit: 'MINUTES') { - sh "mvn -B clean install -Dtest=None" + stage("Build Compact3") { + agent { node { label 'linux' } } + options { timeout(time: 120, unit: 'MINUTES') } + steps { + mavenBuild("jdk8", "-Pcompact3 install -DskipTests", "maven3", true) + warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']] + } } } } - } catch(Exception e) { - notifyBuild("Compile Failure") - throw e - } - - try - { - stage('Javadoc') { - withEnv(mvnEnv) { - timeout(time: 20, unit: 'MINUTES') { - sh "mvn -B javadoc:javadoc" - } - } - } - } catch(Exception e) { - notifyBuild("Javadoc Failure") - throw e - } - - try - { - stage('Test') { - withEnv(mvnEnv) { - timeout(time: 90, unit: 'MINUTES') { - // Run test phase / ignore test failures - sh "mvn -B install -Dmaven.test.failure.ignore=true" - // Report failures in the jenkins UI - step([$class: 'JUnitResultArchiver', - testResults: '**/target/surefire-reports/TEST-*.xml']) - // Collect up the jacoco execution results - def jacocoExcludes = - // build tools - "**/org/eclipse/jetty/ant/**" + - ",**/org/eclipse/jetty/maven/**" + - ",**/org/eclipse/jetty/jspc/**" + - // example code / documentation - ",**/org/eclipse/jetty/embedded/**" + - ",**/org/eclipse/jetty/asyncrest/**" + - ",**/org/eclipse/jetty/demo/**" + - // special environments / late integrations - ",**/org/eclipse/jetty/gcloud/**" + - ",**/org/eclipse/jetty/infinispan/**" + - ",**/org/eclipse/jetty/osgi/**" + - ",**/org/eclipse/jetty/spring/**" + - ",**/org/eclipse/jetty/http/spi/**" + - // test classes - ",**/org/eclipse/jetty/tests/**" + - ",**/org/eclipse/jetty/test/**"; - step([$class: 'JacocoPublisher', - inclusionPattern: '**/org/eclipse/jetty/**/*.class', - exclusionPattern: jacocoExcludes, - execPattern: '**/target/jacoco.exec', - classPattern: '**/target/classes', - sourcePattern: '**/src/main/java']) - // Report on Maven and Javadoc warnings - step([$class: 'WarningsPublisher', - consoleParsers: [ - [parserName: 'Maven'], - [parserName: 'JavaDoc'], - [parserName: 'JavaC'] - ]]) - } - if(isUnstable()) - { - notifyBuild("Unstable / Test Errors") - } - } - } - } catch(Exception e) { - notifyBuild("Test Failure") - throw e - } - - try - { - stage 'Compact3' - - dir("aggregates/jetty-all-compact3") { - withEnv(mvnEnv) { - sh "mvn -B -Pcompact3 clean install" - } - } - } catch(Exception e) { - notifyBuild("Compact3 Failure") - throw e } } -// True if this build is part of the "active" branches -// for Jetty. -def isActiveBranch() -{ - def branchName = "${env.BRANCH_NAME}" - return ( branchName == "master" || - branchName.startsWith("jetty-") ); -} +/** + * To other developers, if you are using this method above, please use the following syntax. + * + * mavenBuild("", " " + * + * @param jdk the jdk tool name (in jenkins) to use for this build + * @param cmdline the command line in " "`format. + * @return the Jenkinsfile step representing a maven build + */ +def mavenBuild(jdk, cmdline, mvnName, junitPublishDisabled) { + def localRepo = "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}" // ".repository" // + def settingsName = 'oss-settings.xml' + def mavenOpts = '-Xms1g -Xmx4g -Djava.awt.headless=true' -// Test if the Jenkins Pipeline or Step has marked the -// current build as unstable -def isUnstable() -{ - return currentBuild.result == "UNSTABLE" -} - -// Send a notification about the build status -def notifyBuild(String buildStatus) -{ - if ( !isActiveBranch() ) - { - // don't send notifications on transient branches - return + withMaven( + maven: mvnName, + jdk: "$jdk", + publisherStrategy: 'EXPLICIT', + globalMavenSettingsConfig: settingsName, + options: [junitPublisher(disabled: junitPublishDisabled),mavenLinkerPublisher(disabled: false),pipelineGraphPublisher(disabled: false)], + mavenOpts: mavenOpts, + mavenLocalRepo: localRepo) { + // Some common Maven command line + provided command line + sh "mvn -V -B -T3 -e -Dmaven.test.failure.ignore=true -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + env.JENKINS_HOME } - - // default the value - buildStatus = buildStatus ?: "UNKNOWN" - - def email = "${env.EMAILADDRESS}" - def summary = "${env.JOB_NAME}#${env.BUILD_NUMBER} - ${buildStatus}" - def detail = """

Job: ${env.JOB_NAME} [#${env.BUILD_NUMBER}]

-

${buildStatus}

- - - - -
Build${env.BUILD_URL}
Console${env.BUILD_URL}console
Test Report${env.BUILD_URL}testReport/
- """ - - emailext ( - to: email, - subject: summary, - body: detail - ) } // vim: et:ts=2:sw=2:ft=groovy From 0638ad1bd9fafd97e802f5cc3065272fbba1a78d Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 3 Apr 2019 18:48:55 +1000 Subject: [PATCH 38/74] do not activate mongodb test Signed-off-by: olivier lamy --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1eb73441ed8..6f4be90b3b6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,7 +11,7 @@ pipeline { agent { node { label 'linux' } } options { timeout(time: 120, unit: 'MINUTES') } steps { - mavenBuild("jdk8", "-Pmongodb install", "maven3", false) + mavenBuild("jdk8", "install", "maven3", false) // Collect up the jacoco execution results (only on main build) jacoco inclusionPattern: '**/org/eclipse/jetty/**/*.class', exclusionPattern: '' + From edaefdbb3bd999c59bad1a41647117f42e8c37ff Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 3 Apr 2019 11:56:07 -0500 Subject: [PATCH 39/74] Fixing CRLF files --- .../src/main/asciidoc/index-docinfo.xml | 184 ++-- .../jetty/http/spi/HttpSpiContextHandler.java | 324 +++---- .../jetty/http/spi/JettyHttpContext.java | 222 ++--- .../http/spi/JettyHttpExchangeDelegate.java | 466 +++++----- .../http/spi/JettyHttpServerProvider.java | 160 ++-- .../jetty/maven/plugin/JettyDeployWar.java | 156 ++-- .../jetty/security/AliasedConstraintTest.java | 364 ++++---- .../jetty/servlets/ThreadStarvationTest.java | 818 +++++++++--------- .../org/eclipse/jetty/start/BaseHomeTest.java | 428 ++++----- .../jetty/start/ConfigurationAssert.java | 568 ++++++------ 10 files changed, 1845 insertions(+), 1845 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/index-docinfo.xml b/jetty-documentation/src/main/asciidoc/index-docinfo.xml index 8fcb9cf2f2b..8a6f6c2bf36 100644 --- a/jetty-documentation/src/main/asciidoc/index-docinfo.xml +++ b/jetty-documentation/src/main/asciidoc/index-docinfo.xml @@ -1,96 +1,96 @@ 1995-2017 Mort Bay Consulting Pty. Ltd. - - - - {revnumber} - - - - + + + + {revnumber} + + + + This documentation is produced and contributed to under the Eclipse Public License v1.0. - - - - - jetty - servlet - servlet-api - cometd - http - websocket - eclipse - maven - java - server - software - - - - - Jan - Bartel - - - Jetty - Project Lead - - - - - Thomas - Becker - - - Jetty - Committer - - - - - Simone - Bordet - - - Jetty - Committer - - - - - Joakim - Erdfelt - - - Jetty - Committer - - - - - Jesse - McConnell - - - Jetty - Committer - - - - - Greg - Wilkins - - - Jetty - Project Lead - - - - - Shirley - Boulay - - - + + + + + jetty + servlet + servlet-api + cometd + http + websocket + eclipse + maven + java + server + software + + + + + Jan + Bartel + + + Jetty + Project Lead + + + + + Thomas + Becker + + + Jetty + Committer + + + + + Simone + Bordet + + + Jetty + Committer + + + + + Joakim + Erdfelt + + + Jetty + Committer + + + + + Jesse + McConnell + + + Jetty + Committer + + + + + Greg + Wilkins + + + Jetty + Project Lead + + + + + Shirley + Boulay + + + diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java index 8e9028836b7..0627db74bcc 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java @@ -1,162 +1,162 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.Authenticator.Result; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpPrincipal; - -/** - * Jetty handler that bridges requests to {@link HttpHandler}. - */ -public class HttpSpiContextHandler extends ContextHandler -{ - public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class); - - private HttpContext _httpContext; - - private HttpHandler _httpHandler; - - public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler) - { - this._httpContext = httpContext; - this._httpHandler = httpHandler; - } - - @Override - public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException - { - if (!target.startsWith(getContextPath())) - { - return; - } - - HttpExchange jettyHttpExchange; - if (baseRequest.isSecure()) - { - jettyHttpExchange = new JettyHttpsExchange(_httpContext,req,resp); - } - else - { - jettyHttpExchange = new JettyHttpExchange(_httpContext,req,resp); - } - - // TODO: add filters processing - - try - { - Authenticator auth = _httpContext.getAuthenticator(); - if (auth != null) - { - handleAuthentication(resp,jettyHttpExchange,auth); - } - else - { - _httpHandler.handle(jettyHttpExchange); - } - } - catch (Exception ex) - { - LOG.debug(ex); - PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody()); - - resp.setStatus(500); - writer.println("

HTTP ERROR: 500

"); - writer.println("
INTERNAL_SERVER_ERROR
"); - writer.println("

RequestURI=" + StringUtil.sanitizeXmlString(req.getRequestURI()) + "

"); - - if (LOG.isDebugEnabled()) - { - writer.println("
");
-                ex.printStackTrace(writer);
-                writer.println("
"); - } - - baseRequest.getHttpChannel().getHttpConfiguration().writePoweredBy(writer,"

","

"); - - writer.close(); - } - finally - { - baseRequest.setHandled(true); - } - - } - - private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException - { - Result result = auth.authenticate(httpExchange); - if (result instanceof Authenticator.Failure) - { - int rc = ((Authenticator.Failure)result).getResponseCode(); - for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) - { - for (String value : header.getValue()) - resp.addHeader(header.getKey(),value); - } - resp.sendError(rc); - } - else if (result instanceof Authenticator.Retry) - { - int rc = ((Authenticator.Retry)result).getResponseCode(); - for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) - { - for (String value : header.getValue()) - resp.addHeader(header.getKey(),value); - } - resp.setStatus(rc); - resp.flushBuffer(); - } - else if (result instanceof Authenticator.Success) - { - HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal(); - ((JettyExchange)httpExchange).setPrincipal(principal); - _httpHandler.handle(httpExchange); - } - } - - public HttpHandler getHttpHandler() - { - return _httpHandler; - } - - public void setHttpHandler(HttpHandler handler) - { - this._httpHandler = handler; - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.Authenticator.Result; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpPrincipal; + +/** + * Jetty handler that bridges requests to {@link HttpHandler}. + */ +public class HttpSpiContextHandler extends ContextHandler +{ + public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class); + + private HttpContext _httpContext; + + private HttpHandler _httpHandler; + + public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler) + { + this._httpContext = httpContext; + this._httpHandler = httpHandler; + } + + @Override + public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException + { + if (!target.startsWith(getContextPath())) + { + return; + } + + HttpExchange jettyHttpExchange; + if (baseRequest.isSecure()) + { + jettyHttpExchange = new JettyHttpsExchange(_httpContext,req,resp); + } + else + { + jettyHttpExchange = new JettyHttpExchange(_httpContext,req,resp); + } + + // TODO: add filters processing + + try + { + Authenticator auth = _httpContext.getAuthenticator(); + if (auth != null) + { + handleAuthentication(resp,jettyHttpExchange,auth); + } + else + { + _httpHandler.handle(jettyHttpExchange); + } + } + catch (Exception ex) + { + LOG.debug(ex); + PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody()); + + resp.setStatus(500); + writer.println("

HTTP ERROR: 500

"); + writer.println("
INTERNAL_SERVER_ERROR
"); + writer.println("

RequestURI=" + StringUtil.sanitizeXmlString(req.getRequestURI()) + "

"); + + if (LOG.isDebugEnabled()) + { + writer.println("
");
+                ex.printStackTrace(writer);
+                writer.println("
"); + } + + baseRequest.getHttpChannel().getHttpConfiguration().writePoweredBy(writer,"

","

"); + + writer.close(); + } + finally + { + baseRequest.setHandled(true); + } + + } + + private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException + { + Result result = auth.authenticate(httpExchange); + if (result instanceof Authenticator.Failure) + { + int rc = ((Authenticator.Failure)result).getResponseCode(); + for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) + { + for (String value : header.getValue()) + resp.addHeader(header.getKey(),value); + } + resp.sendError(rc); + } + else if (result instanceof Authenticator.Retry) + { + int rc = ((Authenticator.Retry)result).getResponseCode(); + for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) + { + for (String value : header.getValue()) + resp.addHeader(header.getKey(),value); + } + resp.setStatus(rc); + resp.flushBuffer(); + } + else if (result instanceof Authenticator.Success) + { + HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal(); + ((JettyExchange)httpExchange).setPrincipal(principal); + _httpHandler.handle(httpExchange); + } + } + + public HttpHandler getHttpHandler() + { + return _httpHandler; + } + + public void setHttpHandler(HttpHandler handler) + { + this._httpHandler = handler; + } + +} diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java index 39d2285addb..18b45d99ea5 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java @@ -1,111 +1,111 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.Filter; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - -/** - * Jetty implementation of {@link com.sun.net.httpserver.HttpContext} - */ -public class JettyHttpContext extends com.sun.net.httpserver.HttpContext -{ - - private HttpSpiContextHandler _jettyContextHandler; - - private HttpServer _server; - - private Map _attributes = new HashMap(); - - private List _filters = new ArrayList(); - - private Authenticator _authenticator; - - - protected JettyHttpContext(HttpServer server, String path, - HttpHandler handler) - { - this._server = server; - _jettyContextHandler = new HttpSpiContextHandler(this, handler); - _jettyContextHandler.setContextPath(path); - } - - protected HttpSpiContextHandler getJettyContextHandler() - { - return _jettyContextHandler; - } - - @Override - public HttpHandler getHandler() - { - return _jettyContextHandler.getHttpHandler(); - } - - @Override - public void setHandler(HttpHandler h) - { - _jettyContextHandler.setHttpHandler(h); - } - - @Override - public String getPath() - { - return _jettyContextHandler.getContextPath(); - } - - @Override - public HttpServer getServer() - { - return _server; - } - - @Override - public Map getAttributes() - { - return _attributes; - } - - @Override - public List getFilters() - { - return _filters; - } - - @Override - public Authenticator setAuthenticator(Authenticator auth) - { - Authenticator previous = _authenticator; - _authenticator = auth; - return previous; - } - - @Override - public Authenticator getAuthenticator() - { - return _authenticator; - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.Filter; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +/** + * Jetty implementation of {@link com.sun.net.httpserver.HttpContext} + */ +public class JettyHttpContext extends com.sun.net.httpserver.HttpContext +{ + + private HttpSpiContextHandler _jettyContextHandler; + + private HttpServer _server; + + private Map _attributes = new HashMap(); + + private List _filters = new ArrayList(); + + private Authenticator _authenticator; + + + protected JettyHttpContext(HttpServer server, String path, + HttpHandler handler) + { + this._server = server; + _jettyContextHandler = new HttpSpiContextHandler(this, handler); + _jettyContextHandler.setContextPath(path); + } + + protected HttpSpiContextHandler getJettyContextHandler() + { + return _jettyContextHandler; + } + + @Override + public HttpHandler getHandler() + { + return _jettyContextHandler.getHttpHandler(); + } + + @Override + public void setHandler(HttpHandler h) + { + _jettyContextHandler.setHttpHandler(h); + } + + @Override + public String getPath() + { + return _jettyContextHandler.getContextPath(); + } + + @Override + public HttpServer getServer() + { + return _server; + } + + @Override + public Map getAttributes() + { + return _attributes; + } + + @Override + public List getFilters() + { + return _filters; + } + + @Override + public Authenticator setAuthenticator(Authenticator auth) + { + Authenticator previous = _authenticator; + _authenticator = auth; + return previous; + } + + @Override + public Authenticator getAuthenticator() + { + return _authenticator; + } + +} diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java index 8d5d3afb0c0..556efbc81ce 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java @@ -1,233 +1,233 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpPrincipal; - -/** - * Jetty implementation of {@link com.sun.net.httpserver.HttpExchange} - */ -public class JettyHttpExchangeDelegate extends HttpExchange -{ - - private HttpContext _httpContext; - - private HttpServletRequest _req; - - private HttpServletResponse _resp; - - private Headers _responseHeaders = new Headers(); - - private int _responseCode = 0; - - private InputStream _is; - - private OutputStream _os; - - private HttpPrincipal _httpPrincipal; - - JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp) - { - this._httpContext = jaxWsContext; - this._req = req; - this._resp = resp; - try - { - this._is = req.getInputStream(); - this._os = resp.getOutputStream(); - } - catch (IOException ex) - { - throw new RuntimeException(ex); - } - } - - @Override - public Headers getRequestHeaders() - { - Headers headers = new Headers(); - Enumeration en = _req.getHeaderNames(); - while (en.hasMoreElements()) - { - String name = (String)en.nextElement(); - Enumeration en2 = _req.getHeaders(name); - while (en2.hasMoreElements()) - { - String value = (String)en2.nextElement(); - headers.add(name,value); - } - } - return headers; - } - - @Override - public Headers getResponseHeaders() - { - return _responseHeaders; - } - - @Override - public URI getRequestURI() - { - try - { - String uriAsString = _req.getRequestURI(); - if (_req.getQueryString() != null) - { - uriAsString += "?" + _req.getQueryString(); - } - - return new URI(uriAsString); - } - catch (URISyntaxException ex) - { - throw new RuntimeException(ex); - } - } - - @Override - public String getRequestMethod() - { - return _req.getMethod(); - } - - @Override - public HttpContext getHttpContext() - { - return _httpContext; - } - - @Override - public void close() - { - try - { - _resp.getOutputStream().close(); - } - catch (IOException ex) - { - throw new RuntimeException(ex); - } - } - - @Override - public InputStream getRequestBody() - { - return _is; - } - - @Override - public OutputStream getResponseBody() - { - return _os; - } - - @Override - public void sendResponseHeaders(int rCode, long responseLength) throws IOException - { - this._responseCode = rCode; - - for (Map.Entry> stringListEntry : _responseHeaders.entrySet()) - { - String name = stringListEntry.getKey(); - List values = stringListEntry.getValue(); - - for (String value : values) - { - _resp.setHeader(name,value); - } - } - if (responseLength > 0) - { - _resp.setHeader("content-length","" + responseLength); - } - _resp.setStatus(rCode); - } - - @Override - public InetSocketAddress getRemoteAddress() - { - return new InetSocketAddress(_req.getRemoteAddr(),_req.getRemotePort()); - } - - @Override - public int getResponseCode() - { - return _responseCode; - } - - @Override - public InetSocketAddress getLocalAddress() - { - return new InetSocketAddress(_req.getLocalAddr(),_req.getLocalPort()); - } - - @Override - public String getProtocol() - { - return _req.getProtocol(); - } - - @Override - public Object getAttribute(String name) - { - return _req.getAttribute(name); - } - - @Override - public void setAttribute(String name, Object value) - { - _req.setAttribute(name,value); - } - - @Override - public void setStreams(InputStream i, OutputStream o) - { - _is = i; - _os = o; - } - - @Override - public HttpPrincipal getPrincipal() - { - return _httpPrincipal; - } - - public void setPrincipal(HttpPrincipal principal) - { - this._httpPrincipal = principal; - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpPrincipal; + +/** + * Jetty implementation of {@link com.sun.net.httpserver.HttpExchange} + */ +public class JettyHttpExchangeDelegate extends HttpExchange +{ + + private HttpContext _httpContext; + + private HttpServletRequest _req; + + private HttpServletResponse _resp; + + private Headers _responseHeaders = new Headers(); + + private int _responseCode = 0; + + private InputStream _is; + + private OutputStream _os; + + private HttpPrincipal _httpPrincipal; + + JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp) + { + this._httpContext = jaxWsContext; + this._req = req; + this._resp = resp; + try + { + this._is = req.getInputStream(); + this._os = resp.getOutputStream(); + } + catch (IOException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public Headers getRequestHeaders() + { + Headers headers = new Headers(); + Enumeration en = _req.getHeaderNames(); + while (en.hasMoreElements()) + { + String name = (String)en.nextElement(); + Enumeration en2 = _req.getHeaders(name); + while (en2.hasMoreElements()) + { + String value = (String)en2.nextElement(); + headers.add(name,value); + } + } + return headers; + } + + @Override + public Headers getResponseHeaders() + { + return _responseHeaders; + } + + @Override + public URI getRequestURI() + { + try + { + String uriAsString = _req.getRequestURI(); + if (_req.getQueryString() != null) + { + uriAsString += "?" + _req.getQueryString(); + } + + return new URI(uriAsString); + } + catch (URISyntaxException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public String getRequestMethod() + { + return _req.getMethod(); + } + + @Override + public HttpContext getHttpContext() + { + return _httpContext; + } + + @Override + public void close() + { + try + { + _resp.getOutputStream().close(); + } + catch (IOException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public InputStream getRequestBody() + { + return _is; + } + + @Override + public OutputStream getResponseBody() + { + return _os; + } + + @Override + public void sendResponseHeaders(int rCode, long responseLength) throws IOException + { + this._responseCode = rCode; + + for (Map.Entry> stringListEntry : _responseHeaders.entrySet()) + { + String name = stringListEntry.getKey(); + List values = stringListEntry.getValue(); + + for (String value : values) + { + _resp.setHeader(name,value); + } + } + if (responseLength > 0) + { + _resp.setHeader("content-length","" + responseLength); + } + _resp.setStatus(rCode); + } + + @Override + public InetSocketAddress getRemoteAddress() + { + return new InetSocketAddress(_req.getRemoteAddr(),_req.getRemotePort()); + } + + @Override + public int getResponseCode() + { + return _responseCode; + } + + @Override + public InetSocketAddress getLocalAddress() + { + return new InetSocketAddress(_req.getLocalAddr(),_req.getLocalPort()); + } + + @Override + public String getProtocol() + { + return _req.getProtocol(); + } + + @Override + public Object getAttribute(String name) + { + return _req.getAttribute(name); + } + + @Override + public void setAttribute(String name, Object value) + { + _req.setAttribute(name,value); + } + + @Override + public void setStreams(InputStream i, OutputStream o) + { + _is = i; + _os = o; + } + + @Override + public HttpPrincipal getPrincipal() + { + return _httpPrincipal; + } + + public void setPrincipal(HttpPrincipal principal) + { + this._httpPrincipal = principal; + } + +} diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java index 82575efa6c2..423b9420545 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java @@ -1,80 +1,80 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsServer; -import com.sun.net.httpserver.spi.HttpServerProvider; - -import java.io.IOException; -import java.net.InetSocketAddress; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.DefaultHandler; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.eclipse.jetty.util.thread.ThreadPool; - -/** - * Jetty implementation of Java HTTP Server SPI - */ -public class JettyHttpServerProvider extends HttpServerProvider -{ - - private static Server _server; - - public static void setServer(Server server) - { - _server = server; - } - - @Override - public HttpServer createHttpServer(InetSocketAddress addr, int backlog) - throws IOException - { - Server server = _server; - boolean shared = true; - - if (server == null) - { - ThreadPool threadPool = new DelegatingThreadPool(new QueuedThreadPool()); - server = new Server(threadPool); - - HandlerCollection handlerCollection = new HandlerCollection(); - handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()}); - server.setHandler(handlerCollection); - - shared = false; - } - - JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared); - if (addr != null) - jettyHttpServer.bind(addr, backlog); - return jettyHttpServer; - } - - @Override - public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException - { - throw new UnsupportedOperationException(); - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsServer; +import com.sun.net.httpserver.spi.HttpServerProvider; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.ThreadPool; + +/** + * Jetty implementation of Java HTTP Server SPI + */ +public class JettyHttpServerProvider extends HttpServerProvider +{ + + private static Server _server; + + public static void setServer(Server server) + { + _server = server; + } + + @Override + public HttpServer createHttpServer(InetSocketAddress addr, int backlog) + throws IOException + { + Server server = _server; + boolean shared = true; + + if (server == null) + { + ThreadPool threadPool = new DelegatingThreadPool(new QueuedThreadPool()); + server = new Server(threadPool); + + HandlerCollection handlerCollection = new HandlerCollection(); + handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()}); + server.setHandler(handlerCollection); + + shared = false; + } + + JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared); + if (addr != null) + jettyHttpServer.bind(addr, backlog); + return jettyHttpServer; + } + + @Override + public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException + { + throw new UnsupportedOperationException(); + } + +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java index d998a42e222..c63dadb3b17 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java @@ -1,78 +1,78 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; - -/** - *

- * This goal is used to run Jetty with a pre-assembled war. - *

- *

- * It accepts exactly the same options as the run-war goal. - * However, it doesn't assume that the current artifact is a - * webapp and doesn't try to assemble it into a war before its execution. - * So using it makes sense only when used in conjunction with the - * war configuration parameter pointing to a pre-built WAR. - *

- *

- * This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested - * HTTP client components. - *

- * - * @goal deploy-war - * @requiresDependencyResolution runtime - * @execute phase="validate" - * @description Deploy a pre-assembled war - * - */ -public class JettyDeployWar extends JettyRunWarMojo -{ - - - /** - * If true, the plugin should continue and not block. Otherwise the - * plugin will block further execution and you will need to use - * cntrl-c to stop it. - * - * - * @parameter default-value="true" - */ - protected boolean daemon = true; - - - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - nonblocking = daemon; - super.execute(); - } - - - - @Override - public void finishConfigurationBeforeStart() throws Exception - { - super.finishConfigurationBeforeStart(); - //only stop the server at shutdown if we are blocking - server.setStopAtShutdown(!nonblocking); - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.maven.plugin; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + *

+ * This goal is used to run Jetty with a pre-assembled war. + *

+ *

+ * It accepts exactly the same options as the run-war goal. + * However, it doesn't assume that the current artifact is a + * webapp and doesn't try to assemble it into a war before its execution. + * So using it makes sense only when used in conjunction with the + * war configuration parameter pointing to a pre-built WAR. + *

+ *

+ * This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested + * HTTP client components. + *

+ * + * @goal deploy-war + * @requiresDependencyResolution runtime + * @execute phase="validate" + * @description Deploy a pre-assembled war + * + */ +public class JettyDeployWar extends JettyRunWarMojo +{ + + + /** + * If true, the plugin should continue and not block. Otherwise the + * plugin will block further execution and you will need to use + * cntrl-c to stop it. + * + * + * @parameter default-value="true" + */ + protected boolean daemon = true; + + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + nonblocking = daemon; + super.execute(); + } + + + + @Override + public void finishConfigurationBeforeStart() throws Exception + { + super.finishConfigurationBeforeStart(); + //only stop the server at shutdown if we are blocking + server.setStopAtShutdown(!nonblocking); + } + +} diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java index 0237b4174fe..164a7e27c12 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java @@ -1,182 +1,182 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.LocalConnector; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.DefaultHandler; -import org.eclipse.jetty.server.handler.HandlerList; -import org.eclipse.jetty.server.handler.ResourceHandler; -import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.util.security.Password; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -/** - * Some requests for static data that is served by ResourceHandler, but some is secured. - *

- * This is mainly here to test security bypass techniques using aliased names that should be caught. - */ -@RunWith(Parameterized.class) -public class AliasedConstraintTest -{ - private static final String TEST_REALM = "TestRealm"; - private static Server server; - private static LocalConnector connector; - private static ConstraintSecurityHandler security; - - @BeforeClass - public static void startServer() throws Exception - { - server = new Server(); - connector = new LocalConnector(server); - server.setConnectors(new Connector[] { connector }); - - ContextHandler context = new ContextHandler(); - SessionHandler session = new SessionHandler(); - - HashLoginService loginService = new HashLoginService(TEST_REALM); - loginService.putUser("user0",new Password("password"),new String[] {}); - loginService.putUser("user",new Password("password"),new String[] { "user" }); - loginService.putUser("user2",new Password("password"),new String[] { "user" }); - loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" }); - loginService.putUser("user3",new Password("password"),new String[] { "foo" }); - - context.setContextPath("/ctx"); - context.setResourceBase(MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath()); - - HandlerList handlers = new HandlerList(); - handlers.setHandlers(new Handler[]{context,new DefaultHandler()}); - server.setHandler(handlers); - context.setHandler(session); - // context.addAliasCheck(new AllowSymLinkAliasChecker()); - - server.addBean(loginService); - - security = new ConstraintSecurityHandler(); - session.setHandler(security); - ResourceHandler handler = new ResourceHandler(); - security.setHandler(handler); - - List constraints = new ArrayList<>(); - - Constraint constraint0 = new Constraint(); - constraint0.setAuthenticate(true); - constraint0.setName("forbid"); - ConstraintMapping mapping0 = new ConstraintMapping(); - mapping0.setPathSpec("/forbid/*"); - mapping0.setConstraint(constraint0); - constraints.add(mapping0); - - Set knownRoles = new HashSet<>(); - knownRoles.add("user"); - knownRoles.add("administrator"); - - security.setConstraintMappings(constraints,knownRoles); - server.start(); - } - - @AfterClass - public static void stopServer() throws Exception - { - server.stop(); - } - - @Parameters(name = "{0}: {1}") - public static Collection data() - { - List data = new ArrayList<>(); - - final String OPENCONTENT = "this is open content"; - - data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); - data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null }); - data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null }); - data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); - data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); - data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); - data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null }); - - return data; - } - - @Parameter(value = 0) - public String uri; - - @Parameter(value = 1) - public int expectedStatusCode; - - @Parameter(value = 2) - public String expectedContent; - - @Test - public void testAccess() throws Exception - { - StringBuilder request = new StringBuilder(); - request.append("GET ").append(uri).append(" HTTP/1.1\r\n"); - request.append("Host: localhost\r\n"); - request.append("Connection: close\r\n"); - request.append("\r\n"); - - String response = connector.getResponses(request.toString()); - - switch (expectedStatusCode) - { - case 200: - assertThat(response,startsWith("HTTP/1.1 200 OK")); - break; - case 403: - assertThat(response,startsWith("HTTP/1.1 403 Forbidden")); - break; - case 404: - assertThat(response,startsWith("HTTP/1.1 404 Not Found")); - break; - default: - fail("Write a handler for response status code: " + expectedStatusCode); - break; - } - - if (expectedContent != null) - { - assertThat(response,containsString("this is open content")); - } - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerList; +import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Password; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** + * Some requests for static data that is served by ResourceHandler, but some is secured. + *

+ * This is mainly here to test security bypass techniques using aliased names that should be caught. + */ +@RunWith(Parameterized.class) +public class AliasedConstraintTest +{ + private static final String TEST_REALM = "TestRealm"; + private static Server server; + private static LocalConnector connector; + private static ConstraintSecurityHandler security; + + @BeforeClass + public static void startServer() throws Exception + { + server = new Server(); + connector = new LocalConnector(server); + server.setConnectors(new Connector[] { connector }); + + ContextHandler context = new ContextHandler(); + SessionHandler session = new SessionHandler(); + + HashLoginService loginService = new HashLoginService(TEST_REALM); + loginService.putUser("user0",new Password("password"),new String[] {}); + loginService.putUser("user",new Password("password"),new String[] { "user" }); + loginService.putUser("user2",new Password("password"),new String[] { "user" }); + loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" }); + loginService.putUser("user3",new Password("password"),new String[] { "foo" }); + + context.setContextPath("/ctx"); + context.setResourceBase(MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath()); + + HandlerList handlers = new HandlerList(); + handlers.setHandlers(new Handler[]{context,new DefaultHandler()}); + server.setHandler(handlers); + context.setHandler(session); + // context.addAliasCheck(new AllowSymLinkAliasChecker()); + + server.addBean(loginService); + + security = new ConstraintSecurityHandler(); + session.setHandler(security); + ResourceHandler handler = new ResourceHandler(); + security.setHandler(handler); + + List constraints = new ArrayList<>(); + + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(true); + constraint0.setName("forbid"); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/forbid/*"); + mapping0.setConstraint(constraint0); + constraints.add(mapping0); + + Set knownRoles = new HashSet<>(); + knownRoles.add("user"); + knownRoles.add("administrator"); + + security.setConstraintMappings(constraints,knownRoles); + server.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + server.stop(); + } + + @Parameters(name = "{0}: {1}") + public static Collection data() + { + List data = new ArrayList<>(); + + final String OPENCONTENT = "this is open content"; + + data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); + data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null }); + data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null }); + data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); + data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); + data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); + data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null }); + + return data; + } + + @Parameter(value = 0) + public String uri; + + @Parameter(value = 1) + public int expectedStatusCode; + + @Parameter(value = 2) + public String expectedContent; + + @Test + public void testAccess() throws Exception + { + StringBuilder request = new StringBuilder(); + request.append("GET ").append(uri).append(" HTTP/1.1\r\n"); + request.append("Host: localhost\r\n"); + request.append("Connection: close\r\n"); + request.append("\r\n"); + + String response = connector.getResponses(request.toString()); + + switch (expectedStatusCode) + { + case 200: + assertThat(response,startsWith("HTTP/1.1 200 OK")); + break; + case 403: + assertThat(response,startsWith("HTTP/1.1 403 Forbidden")); + break; + case 404: + assertThat(response,startsWith("HTTP/1.1 404 Not Found")); + break; + default: + fail("Write a handler for response status code: " + expectedStatusCode); + break; + } + + if (expectedContent != null) + { + assertThat(response,containsString("this is open content")); + } + } +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/ThreadStarvationTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/ThreadStarvationTest.java index 9a7ed1650f2..b52db506bc2 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/ThreadStarvationTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/ThreadStarvationTest.java @@ -1,409 +1,409 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.servlets; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.nio.ByteBuffer; -import java.nio.channels.SelectionKey; -import java.nio.channels.SocketChannel; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.BrokenBarrierException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.CyclicBarrier; -import java.util.concurrent.Exchanger; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.io.ManagedSelector; -import org.eclipse.jetty.io.SelectChannelEndPoint; -import org.eclipse.jetty.server.HttpChannel; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.handler.AbstractHandler; -import org.eclipse.jetty.servlet.DefaultServlet; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.toolchain.test.TestTracker; -import org.eclipse.jetty.toolchain.test.annotation.Slow; -import org.eclipse.jetty.util.log.StacklessLogging; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.junit.After; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; - -public class ThreadStarvationTest -{ - @Rule - public TestTracker tracker = new TestTracker(); - private Server _server; - - @After - public void dispose() throws Exception - { - if (_server != null) - _server.stop(); - } - - @Test - @Slow - public void testDefaultServletSuccess() throws Exception - { - int maxThreads = 10; - QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads); - threadPool.setDetailedDump(true); - _server = new Server(threadPool); - - // Prepare a big file to download. - File directory = MavenTestingUtils.getTargetTestingDir(); - Files.createDirectories(directory.toPath()); - String resourceName = "resource.bin"; - Path resourcePath = Paths.get(directory.getPath(), resourceName); - try (OutputStream output = Files.newOutputStream(resourcePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) - { - byte[] chunk = new byte[1024]; - Arrays.fill(chunk,(byte)'X'); - chunk[chunk.length-2]='\r'; - chunk[chunk.length-1]='\n'; - for (int i = 0; i < 256 * 1024; ++i) - output.write(chunk); - } - - final CountDownLatch writePending = new CountDownLatch(1); - ServerConnector connector = new ServerConnector(_server, 0, 1) - { - @Override - protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException - { - return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()) - { - @Override - protected void onIncompleteFlush() - { - super.onIncompleteFlush(); - writePending.countDown(); - } - }; - } - }; - connector.setIdleTimeout(Long.MAX_VALUE); - _server.addConnector(connector); - - ServletContextHandler context = new ServletContextHandler(_server, "/"); - context.setResourceBase(directory.toURI().toString()); - context.addServlet(DefaultServlet.class, "/*").setAsyncSupported(false); - _server.setHandler(context); - - _server.start(); - - List sockets = new ArrayList<>(); - for (int i = 0; i < maxThreads*2; ++i) - { - Socket socket = new Socket("localhost", connector.getLocalPort()); - sockets.add(socket); - OutputStream output = socket.getOutputStream(); - String request = "" + - "GET /" + resourceName + " HTTP/1.1\r\n" + - "Host: localhost\r\n" + - "\r\n"; - output.write(request.getBytes(StandardCharsets.UTF_8)); - output.flush(); - Thread.sleep(100); - } - - // Wait for a the servlet to block. - Assert.assertTrue(writePending.await(5, TimeUnit.SECONDS)); - - long expected = Files.size(resourcePath); - byte[] buffer = new byte[48 * 1024]; - List> totals = new ArrayList<>(); - for (Socket socket : sockets) - { - final Exchanger x = new Exchanger<>(); - totals.add(x); - final InputStream input = socket.getInputStream(); - - new Thread() - { - @Override - public void run() - { - long total=0; - try - { - // look for CRLFCRLF - StringBuilder header = new StringBuilder(); - int state=0; - while (state<4 && header.length()<2048) - { - int ch=input.read(); - if (ch<0) - break; - header.append((char)ch); - switch(state) - { - case 0: - if (ch=='\r') - state=1; - break; - case 1: - if (ch=='\n') - state=2; - else - state=0; - break; - case 2: - if (ch=='\r') - state=3; - else - state=0; - break; - case 3: - if (ch=='\n') - state=4; - else - state=0; - break; - } - } - - while (total x : totals) - { - Long total = x.exchange(-1L,10000,TimeUnit.SECONDS); - Assert.assertEquals(expected,total.longValue()); - } - - // We could read everything, good. - for (Socket socket : sockets) - socket.close(); - } - - @Test - public void testFailureStarvation() throws Exception - { - try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) - { - int acceptors = 0; - int selectors = 1; - int maxThreads = 10; - final int barried=maxThreads-acceptors-selectors; - final CyclicBarrier barrier = new CyclicBarrier(barried); - - - QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads); - threadPool.setDetailedDump(true); - _server = new Server(threadPool); - - - ServerConnector connector = new ServerConnector(_server, acceptors, selectors) - { - @Override - protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException - { - return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()) - { - - @Override - public boolean flush(ByteBuffer... buffers) throws IOException - { - super.flush(buffers[0]); - throw new IOException("TEST FAILURE"); - } - - }; - } - }; - connector.setIdleTimeout(Long.MAX_VALUE); - _server.addConnector(connector); - - final AtomicInteger count = new AtomicInteger(0); - _server.setHandler(new AbstractHandler() - { - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - int c=count.getAndIncrement(); - try - { - if (c sockets = new ArrayList<>(); - for (int i = 0; i < maxThreads*2; ++i) - { - Socket socket = new Socket("localhost", connector.getLocalPort()); - sockets.add(socket); - OutputStream output = socket.getOutputStream(); - String request = "" + - "GET / HTTP/1.1\r\n" + - "Host: localhost\r\n" + - // "Connection: close\r\n" + - "\r\n"; - output.write(request.getBytes(StandardCharsets.UTF_8)); - output.flush(); - } - - - byte[] buffer = new byte[48 * 1024]; - List> totals = new ArrayList<>(); - for (Socket socket : sockets) - { - final Exchanger x = new Exchanger<>(); - totals.add(x); - final InputStream input = socket.getInputStream(); - - new Thread() - { - @Override - public void run() - { - int read=0; - try - { - // look for CRLFCRLF - StringBuilder header = new StringBuilder(); - int state=0; - while (state<4 && header.length()<2048) - { - int ch=input.read(); - if (ch<0) - break; - header.append((char)ch); - switch(state) - { - case 0: - if (ch=='\r') - state=1; - break; - case 1: - if (ch=='\n') - state=2; - else - state=0; - break; - case 2: - if (ch=='\r') - state=3; - else - state=0; - break; - case 3: - if (ch=='\n') - state=4; - else - state=0; - break; - } - } - - read=input.read(buffer); - } - catch (IOException e) - { - // e.printStackTrace(); - } - finally - { - try - { - x.exchange(read); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - } - }.start(); - } - - for (Exchanger x : totals) - { - Integer read = x.exchange(-1,10,TimeUnit.SECONDS); - Assert.assertEquals(-1,read.intValue()); - } - - // We could read everything, good. - for (Socket socket : sockets) - socket.close(); - - _server.stop(); - } - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.servlets; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Exchanger; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.io.ManagedSelector; +import org.eclipse.jetty.io.SelectChannelEndPoint; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.toolchain.test.TestTracker; +import org.eclipse.jetty.toolchain.test.annotation.Slow; +import org.eclipse.jetty.util.log.StacklessLogging; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.junit.After; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; + +public class ThreadStarvationTest +{ + @Rule + public TestTracker tracker = new TestTracker(); + private Server _server; + + @After + public void dispose() throws Exception + { + if (_server != null) + _server.stop(); + } + + @Test + @Slow + public void testDefaultServletSuccess() throws Exception + { + int maxThreads = 10; + QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads); + threadPool.setDetailedDump(true); + _server = new Server(threadPool); + + // Prepare a big file to download. + File directory = MavenTestingUtils.getTargetTestingDir(); + Files.createDirectories(directory.toPath()); + String resourceName = "resource.bin"; + Path resourcePath = Paths.get(directory.getPath(), resourceName); + try (OutputStream output = Files.newOutputStream(resourcePath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) + { + byte[] chunk = new byte[1024]; + Arrays.fill(chunk,(byte)'X'); + chunk[chunk.length-2]='\r'; + chunk[chunk.length-1]='\n'; + for (int i = 0; i < 256 * 1024; ++i) + output.write(chunk); + } + + final CountDownLatch writePending = new CountDownLatch(1); + ServerConnector connector = new ServerConnector(_server, 0, 1) + { + @Override + protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException + { + return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()) + { + @Override + protected void onIncompleteFlush() + { + super.onIncompleteFlush(); + writePending.countDown(); + } + }; + } + }; + connector.setIdleTimeout(Long.MAX_VALUE); + _server.addConnector(connector); + + ServletContextHandler context = new ServletContextHandler(_server, "/"); + context.setResourceBase(directory.toURI().toString()); + context.addServlet(DefaultServlet.class, "/*").setAsyncSupported(false); + _server.setHandler(context); + + _server.start(); + + List sockets = new ArrayList<>(); + for (int i = 0; i < maxThreads*2; ++i) + { + Socket socket = new Socket("localhost", connector.getLocalPort()); + sockets.add(socket); + OutputStream output = socket.getOutputStream(); + String request = "" + + "GET /" + resourceName + " HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "\r\n"; + output.write(request.getBytes(StandardCharsets.UTF_8)); + output.flush(); + Thread.sleep(100); + } + + // Wait for a the servlet to block. + Assert.assertTrue(writePending.await(5, TimeUnit.SECONDS)); + + long expected = Files.size(resourcePath); + byte[] buffer = new byte[48 * 1024]; + List> totals = new ArrayList<>(); + for (Socket socket : sockets) + { + final Exchanger x = new Exchanger<>(); + totals.add(x); + final InputStream input = socket.getInputStream(); + + new Thread() + { + @Override + public void run() + { + long total=0; + try + { + // look for CRLFCRLF + StringBuilder header = new StringBuilder(); + int state=0; + while (state<4 && header.length()<2048) + { + int ch=input.read(); + if (ch<0) + break; + header.append((char)ch); + switch(state) + { + case 0: + if (ch=='\r') + state=1; + break; + case 1: + if (ch=='\n') + state=2; + else + state=0; + break; + case 2: + if (ch=='\r') + state=3; + else + state=0; + break; + case 3: + if (ch=='\n') + state=4; + else + state=0; + break; + } + } + + while (total x : totals) + { + Long total = x.exchange(-1L,10000,TimeUnit.SECONDS); + Assert.assertEquals(expected,total.longValue()); + } + + // We could read everything, good. + for (Socket socket : sockets) + socket.close(); + } + + @Test + public void testFailureStarvation() throws Exception + { + try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) + { + int acceptors = 0; + int selectors = 1; + int maxThreads = 10; + final int barried=maxThreads-acceptors-selectors; + final CyclicBarrier barrier = new CyclicBarrier(barried); + + + QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads); + threadPool.setDetailedDump(true); + _server = new Server(threadPool); + + + ServerConnector connector = new ServerConnector(_server, acceptors, selectors) + { + @Override + protected SelectChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException + { + return new SelectChannelEndPoint(channel, selectSet, key, getScheduler(), getIdleTimeout()) + { + + @Override + public boolean flush(ByteBuffer... buffers) throws IOException + { + super.flush(buffers[0]); + throw new IOException("TEST FAILURE"); + } + + }; + } + }; + connector.setIdleTimeout(Long.MAX_VALUE); + _server.addConnector(connector); + + final AtomicInteger count = new AtomicInteger(0); + _server.setHandler(new AbstractHandler() + { + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + int c=count.getAndIncrement(); + try + { + if (c sockets = new ArrayList<>(); + for (int i = 0; i < maxThreads*2; ++i) + { + Socket socket = new Socket("localhost", connector.getLocalPort()); + sockets.add(socket); + OutputStream output = socket.getOutputStream(); + String request = "" + + "GET / HTTP/1.1\r\n" + + "Host: localhost\r\n" + + // "Connection: close\r\n" + + "\r\n"; + output.write(request.getBytes(StandardCharsets.UTF_8)); + output.flush(); + } + + + byte[] buffer = new byte[48 * 1024]; + List> totals = new ArrayList<>(); + for (Socket socket : sockets) + { + final Exchanger x = new Exchanger<>(); + totals.add(x); + final InputStream input = socket.getInputStream(); + + new Thread() + { + @Override + public void run() + { + int read=0; + try + { + // look for CRLFCRLF + StringBuilder header = new StringBuilder(); + int state=0; + while (state<4 && header.length()<2048) + { + int ch=input.read(); + if (ch<0) + break; + header.append((char)ch); + switch(state) + { + case 0: + if (ch=='\r') + state=1; + break; + case 1: + if (ch=='\n') + state=2; + else + state=0; + break; + case 2: + if (ch=='\r') + state=3; + else + state=0; + break; + case 3: + if (ch=='\n') + state=4; + else + state=0; + break; + } + } + + read=input.read(buffer); + } + catch (IOException e) + { + // e.printStackTrace(); + } + finally + { + try + { + x.exchange(read); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } + }.start(); + } + + for (Exchanger x : totals) + { + Integer read = x.exchange(-1,10,TimeUnit.SECONDS); + Assert.assertEquals(-1,read.intValue()); + } + + // We could read everything, good. + for (Socket socket : sockets) + socket.close(); + + _server.stop(); + } + } +} diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java index 18e61875841..aa43ca9d407 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java @@ -1,214 +1,214 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.start; - -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jetty.start.config.ConfigSources; -import org.eclipse.jetty.start.config.JettyBaseConfigSource; -import org.eclipse.jetty.start.config.JettyHomeConfigSource; -import org.eclipse.jetty.toolchain.test.IO; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.junit.Assert; -import org.junit.Test; - -public class BaseHomeTest -{ - public static void assertPathList(BaseHome hb, String message, List expected, PathFinder finder) - { - List actual = new ArrayList<>(); - for (Path path : finder.getHits()) - { - actual.add(hb.toShortForm(path.toFile())); - } - - if (actual.size() != expected.size()) - { - System.out.printf("Actual Path(s): %,d hits%n",actual.size()); - for (String path : actual) - { - System.out.printf(" %s%n",path); - } - System.out.printf("Expected Path(s): %,d entries%n",expected.size()); - for (String path : expected) - { - System.out.printf(" %s%n",path); - } - } - Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); - } - - public static void assertPathList(BaseHome hb, String message, List expected, List paths) - { - List actual = new ArrayList<>(); - for (Path path : paths) - { - actual.add(hb.toShortForm(path.toFile())); - } - - if (actual.size() != expected.size()) - { - System.out.printf("Actual Path(s): %,d hits%n",actual.size()); - for (String path : actual) - { - System.out.printf(" %s%n",path); - } - System.out.printf("Expected Path(s): %,d entries%n",expected.size()); - for (String path : expected) - { - System.out.printf(" %s%n",path); - } - } - Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); - } - - public static void assertFileList(BaseHome hb, String message, List expected, List files) - { - List actual = new ArrayList<>(); - for (File file : files) - { - actual.add(hb.toShortForm(file)); - } - Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); - } - - @Test - public void testGetPath_OnlyHome() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - Path startIni = hb.getPath("start.ini"); - - String ref = hb.toShortForm(startIni); - Assert.assertThat("Reference",ref,startsWith("${jetty.home}")); - - String contents = IO.readToString(startIni.toFile()); - Assert.assertThat("Contents",contents,containsString("Home Ini")); - } - - @Test - public void testGetPaths_OnlyHome() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - List paths = hb.getPaths("start.d/*"); - - List expected = new ArrayList<>(); - expected.add("${jetty.home}/start.d/jmx.ini"); - expected.add("${jetty.home}/start.d/jndi.ini"); - expected.add("${jetty.home}/start.d/jsp.ini"); - expected.add("${jetty.home}/start.d/logging.ini"); - expected.add("${jetty.home}/start.d/ssl.ini"); - FSTest.toOsSeparators(expected); - - assertPathList(hb,"Paths found",expected,paths); - } - - @Test - public void testGetPaths_OnlyHome_InisOnly() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - List paths = hb.getPaths("start.d/*.ini"); - - List expected = new ArrayList<>(); - expected.add("${jetty.home}/start.d/jmx.ini"); - expected.add("${jetty.home}/start.d/jndi.ini"); - expected.add("${jetty.home}/start.d/jsp.ini"); - expected.add("${jetty.home}/start.d/logging.ini"); - expected.add("${jetty.home}/start.d/ssl.ini"); - FSTest.toOsSeparators(expected); - - assertPathList(hb,"Paths found",expected,paths); - } - - @Test - public void testGetPaths_Both() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyBaseConfigSource(baseDir.toPath())); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - List paths = hb.getPaths("start.d/*.ini"); - - List expected = new ArrayList<>(); - expected.add("${jetty.base}/start.d/jmx.ini"); - expected.add("${jetty.home}/start.d/jndi.ini"); - expected.add("${jetty.home}/start.d/jsp.ini"); - expected.add("${jetty.base}/start.d/logging.ini"); - expected.add("${jetty.home}/start.d/ssl.ini"); - expected.add("${jetty.base}/start.d/myapp.ini"); - FSTest.toOsSeparators(expected); - - assertPathList(hb,"Paths found",expected,paths); - } - - @Test - public void testDefault() throws IOException - { - BaseHome bh = new BaseHome(); - Assert.assertThat("Home",bh.getHome(),notNullValue()); - Assert.assertThat("Base",bh.getBase(),notNullValue()); - } - - @Test - public void testGetPath_Both() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyBaseConfigSource(baseDir.toPath())); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - Path startIni = hb.getPath("start.ini"); - - String ref = hb.toShortForm(startIni); - Assert.assertThat("Reference",ref,startsWith("${jetty.base}")); - - String contents = IO.readToString(startIni.toFile()); - Assert.assertThat("Contents",contents,containsString("Base Ini")); - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.start; + +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jetty.start.config.ConfigSources; +import org.eclipse.jetty.start.config.JettyBaseConfigSource; +import org.eclipse.jetty.start.config.JettyHomeConfigSource; +import org.eclipse.jetty.toolchain.test.IO; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Assert; +import org.junit.Test; + +public class BaseHomeTest +{ + public static void assertPathList(BaseHome hb, String message, List expected, PathFinder finder) + { + List actual = new ArrayList<>(); + for (Path path : finder.getHits()) + { + actual.add(hb.toShortForm(path.toFile())); + } + + if (actual.size() != expected.size()) + { + System.out.printf("Actual Path(s): %,d hits%n",actual.size()); + for (String path : actual) + { + System.out.printf(" %s%n",path); + } + System.out.printf("Expected Path(s): %,d entries%n",expected.size()); + for (String path : expected) + { + System.out.printf(" %s%n",path); + } + } + Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); + } + + public static void assertPathList(BaseHome hb, String message, List expected, List paths) + { + List actual = new ArrayList<>(); + for (Path path : paths) + { + actual.add(hb.toShortForm(path.toFile())); + } + + if (actual.size() != expected.size()) + { + System.out.printf("Actual Path(s): %,d hits%n",actual.size()); + for (String path : actual) + { + System.out.printf(" %s%n",path); + } + System.out.printf("Expected Path(s): %,d entries%n",expected.size()); + for (String path : expected) + { + System.out.printf(" %s%n",path); + } + } + Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); + } + + public static void assertFileList(BaseHome hb, String message, List expected, List files) + { + List actual = new ArrayList<>(); + for (File file : files) + { + actual.add(hb.toShortForm(file)); + } + Assert.assertThat(message + ": " + Utils.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); + } + + @Test + public void testGetPath_OnlyHome() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + Path startIni = hb.getPath("start.ini"); + + String ref = hb.toShortForm(startIni); + Assert.assertThat("Reference",ref,startsWith("${jetty.home}")); + + String contents = IO.readToString(startIni.toFile()); + Assert.assertThat("Contents",contents,containsString("Home Ini")); + } + + @Test + public void testGetPaths_OnlyHome() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + List paths = hb.getPaths("start.d/*"); + + List expected = new ArrayList<>(); + expected.add("${jetty.home}/start.d/jmx.ini"); + expected.add("${jetty.home}/start.d/jndi.ini"); + expected.add("${jetty.home}/start.d/jsp.ini"); + expected.add("${jetty.home}/start.d/logging.ini"); + expected.add("${jetty.home}/start.d/ssl.ini"); + FSTest.toOsSeparators(expected); + + assertPathList(hb,"Paths found",expected,paths); + } + + @Test + public void testGetPaths_OnlyHome_InisOnly() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + List paths = hb.getPaths("start.d/*.ini"); + + List expected = new ArrayList<>(); + expected.add("${jetty.home}/start.d/jmx.ini"); + expected.add("${jetty.home}/start.d/jndi.ini"); + expected.add("${jetty.home}/start.d/jsp.ini"); + expected.add("${jetty.home}/start.d/logging.ini"); + expected.add("${jetty.home}/start.d/ssl.ini"); + FSTest.toOsSeparators(expected); + + assertPathList(hb,"Paths found",expected,paths); + } + + @Test + public void testGetPaths_Both() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyBaseConfigSource(baseDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + List paths = hb.getPaths("start.d/*.ini"); + + List expected = new ArrayList<>(); + expected.add("${jetty.base}/start.d/jmx.ini"); + expected.add("${jetty.home}/start.d/jndi.ini"); + expected.add("${jetty.home}/start.d/jsp.ini"); + expected.add("${jetty.base}/start.d/logging.ini"); + expected.add("${jetty.home}/start.d/ssl.ini"); + expected.add("${jetty.base}/start.d/myapp.ini"); + FSTest.toOsSeparators(expected); + + assertPathList(hb,"Paths found",expected,paths); + } + + @Test + public void testDefault() throws IOException + { + BaseHome bh = new BaseHome(); + Assert.assertThat("Home",bh.getHome(),notNullValue()); + Assert.assertThat("Base",bh.getBase(),notNullValue()); + } + + @Test + public void testGetPath_Both() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyBaseConfigSource(baseDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + Path startIni = hb.getPath("start.ini"); + + String ref = hb.toShortForm(startIni); + Assert.assertThat("Reference",ref,startsWith("${jetty.base}")); + + String contents = IO.readToString(startIni.toFile()); + Assert.assertThat("Contents",contents,containsString("Base Ini")); + } +} diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java index fdf4a2d44c7..ebdbdaa42c8 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java @@ -1,284 +1,284 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.start; - -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.jetty.start.Props.Prop; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.junit.Assert; - -public class ConfigurationAssert -{ - /** - * Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file. - * - * @param baseHome - * the BaseHome used. Access it via {@link Main#getBaseHome()} - * @param args - * the StartArgs that has been processed via {@link Main#processCommandLine(String[])} - * @param filename - * the filename of the assertion values - * @throws FileNotFoundException if unable to find the configuration - * @throws IOException if unable to process the configuration - */ - public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException - { - Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toRealPath(); - File file = MavenTestingUtils.getTestResourceFile(filename); - TextFile textFile = new TextFile(file.toPath()); - - // Validate XMLs (order is important) - List expectedXmls = new ArrayList<>(); - for (String line : textFile) - { - if (line.startsWith("XML|")) - { - expectedXmls.add(FS.separators(getValue(line))); - } - } - List actualXmls = new ArrayList<>(); - for (Path xml : args.getXmlFiles()) - { - actualXmls.add(shorten(baseHome,xml,testResourcesDir)); - } - assertOrdered("XML Resolution Order",expectedXmls,actualXmls); - - // Validate LIBs (order is not important) - List expectedLibs = new ArrayList<>(); - for (String line : textFile) - { - if (line.startsWith("LIB|")) - { - expectedLibs.add(FS.separators(getValue(line))); - } - } - List actualLibs = new ArrayList<>(); - for (File path : args.getClasspath()) - { - actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir)); - } - assertContainsUnordered("Libs",expectedLibs,actualLibs); - - // Validate PROPERTIES (order is not important) - Set expectedProperties = new HashSet<>(); - for (String line : textFile) - { - if (line.startsWith("PROP|")) - { - expectedProperties.add(getValue(line)); - } - } - List actualProperties = new ArrayList<>(); - for (Prop prop : args.getProperties()) - { - String name = prop.key; - if ("jetty.home".equals(name) || "jetty.base".equals(name) || - "user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP) || - name.startsWith("java.")) - { - // strip these out from assertion, to make assertions easier. - continue; - } - actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value)); - } - assertContainsUnordered("Properties",expectedProperties,actualProperties); - - // Validate Downloads - List expectedDownloads = new ArrayList<>(); - for (String line : textFile) - { - if (line.startsWith("DOWNLOAD|")) - { - expectedDownloads.add(getValue(line)); - } - } - List actualDownloads = new ArrayList<>(); - for (FileArg darg : args.getFiles()) - { - if (darg.uri != null) - { - actualDownloads.add(String.format("%s|%s",darg.uri,darg.location)); - } - } - assertContainsUnordered("Downloads",expectedDownloads,actualDownloads); - - // Validate Files/Dirs creation - List expectedFiles = new ArrayList<>(); - for(String line: textFile) - { - if(line.startsWith("FILE|")) - { - expectedFiles.add(getValue(line)); - } - } - List actualFiles = new ArrayList<>(); - for(FileArg farg: args.getFiles()) - { - if(farg.uri == null) - { - actualFiles.add(farg.location); - } - } - assertContainsUnordered("Files/Dirs",expectedFiles,actualFiles); - } - - private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir) - { - String value = baseHome.toShortForm(path); - if (value.startsWith("${")) - { - return value; - } - - if (path.startsWith(testResourcesDir)) - { - int len = testResourcesDir.toString().length(); - value = "${maven-test-resources}" + value.substring(len); - } - return value; - } - - public static void assertContainsUnordered(String msg, Collection expectedSet, Collection actualSet) - { - // same size? - boolean mismatch = expectedSet.size() != actualSet.size(); - - // test content - Set missing = new HashSet<>(); - for (String expected : expectedSet) - { - if (!actualSet.contains(expected)) - { - missing.add(expected); - } - } - - if (mismatch || missing.size() > 0) - { - // build up detailed error message - StringWriter message = new StringWriter(); - PrintWriter err = new PrintWriter(message); - - err.printf("%s: Assert Contains (Unordered)",msg); - if (mismatch) - { - err.print(" [size mismatch]"); - } - if (missing.size() >= 0) - { - err.printf(" [%d entries missing]",missing.size()); - } - err.println(); - err.printf("Actual Entries (size: %d)%n",actualSet.size()); - for (String actual : actualSet) - { - char indicator = expectedSet.contains(actual)?' ':'>'; - err.printf("%s| %s%n",indicator,actual); - } - err.printf("Expected Entries (size: %d)%n",expectedSet.size()); - for (String expected : expectedSet) - { - char indicator = actualSet.contains(expected)?' ':'>'; - err.printf("%s| %s%n",indicator,expected); - } - err.flush(); - Assert.fail(message.toString()); - } - } - - public static void assertOrdered(String msg, List expectedList, List actualList) - { - // same size? - boolean mismatch = expectedList.size() != actualList.size(); - - // test content - List badEntries = new ArrayList<>(); - int min = Math.min(expectedList.size(),actualList.size()); - int max = Math.max(expectedList.size(),actualList.size()); - for (int i = 0; i < min; i++) - { - if (!expectedList.get(i).equals(actualList.get(i))) - { - badEntries.add(i); - } - } - for (int i = min; i < max; i++) - { - badEntries.add(i); - } - - if (mismatch || badEntries.size() > 0) - { - // build up detailed error message - StringWriter message = new StringWriter(); - PrintWriter err = new PrintWriter(message); - - err.printf("%s: Assert Contains (Unordered)",msg); - if (mismatch) - { - err.print(" [size mismatch]"); - } - if (badEntries.size() >= 0) - { - err.printf(" [%d entries not matched]",badEntries.size()); - } - err.println(); - err.printf("Actual Entries (size: %d)%n",actualList.size()); - for (int i = 0; i < actualList.size(); i++) - { - String actual = actualList.get(i); - char indicator = badEntries.contains(i)?'>':' '; - err.printf("%s[%d] %s%n",indicator,i,actual); - } - - err.printf("Expected Entries (size: %d)%n",expectedList.size()); - for (int i = 0; i < expectedList.size(); i++) - { - String expected = expectedList.get(i); - char indicator = badEntries.contains(i)?'>':' '; - err.printf("%s[%d] %s%n",indicator,i,expected); - } - err.flush(); - Assert.fail(message.toString()); - } - } - - private static String getValue(String arg) - { - int idx = arg.indexOf('|'); - Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0)); - String value = arg.substring(idx + 1).trim(); - Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0)); - return value; - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.start; + +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.start.Props.Prop; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Assert; + +public class ConfigurationAssert +{ + /** + * Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file. + * + * @param baseHome + * the BaseHome used. Access it via {@link Main#getBaseHome()} + * @param args + * the StartArgs that has been processed via {@link Main#processCommandLine(String[])} + * @param filename + * the filename of the assertion values + * @throws FileNotFoundException if unable to find the configuration + * @throws IOException if unable to process the configuration + */ + public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException + { + Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toRealPath(); + File file = MavenTestingUtils.getTestResourceFile(filename); + TextFile textFile = new TextFile(file.toPath()); + + // Validate XMLs (order is important) + List expectedXmls = new ArrayList<>(); + for (String line : textFile) + { + if (line.startsWith("XML|")) + { + expectedXmls.add(FS.separators(getValue(line))); + } + } + List actualXmls = new ArrayList<>(); + for (Path xml : args.getXmlFiles()) + { + actualXmls.add(shorten(baseHome,xml,testResourcesDir)); + } + assertOrdered("XML Resolution Order",expectedXmls,actualXmls); + + // Validate LIBs (order is not important) + List expectedLibs = new ArrayList<>(); + for (String line : textFile) + { + if (line.startsWith("LIB|")) + { + expectedLibs.add(FS.separators(getValue(line))); + } + } + List actualLibs = new ArrayList<>(); + for (File path : args.getClasspath()) + { + actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir)); + } + assertContainsUnordered("Libs",expectedLibs,actualLibs); + + // Validate PROPERTIES (order is not important) + Set expectedProperties = new HashSet<>(); + for (String line : textFile) + { + if (line.startsWith("PROP|")) + { + expectedProperties.add(getValue(line)); + } + } + List actualProperties = new ArrayList<>(); + for (Prop prop : args.getProperties()) + { + String name = prop.key; + if ("jetty.home".equals(name) || "jetty.base".equals(name) || + "user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP) || + name.startsWith("java.")) + { + // strip these out from assertion, to make assertions easier. + continue; + } + actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value)); + } + assertContainsUnordered("Properties",expectedProperties,actualProperties); + + // Validate Downloads + List expectedDownloads = new ArrayList<>(); + for (String line : textFile) + { + if (line.startsWith("DOWNLOAD|")) + { + expectedDownloads.add(getValue(line)); + } + } + List actualDownloads = new ArrayList<>(); + for (FileArg darg : args.getFiles()) + { + if (darg.uri != null) + { + actualDownloads.add(String.format("%s|%s",darg.uri,darg.location)); + } + } + assertContainsUnordered("Downloads",expectedDownloads,actualDownloads); + + // Validate Files/Dirs creation + List expectedFiles = new ArrayList<>(); + for(String line: textFile) + { + if(line.startsWith("FILE|")) + { + expectedFiles.add(getValue(line)); + } + } + List actualFiles = new ArrayList<>(); + for(FileArg farg: args.getFiles()) + { + if(farg.uri == null) + { + actualFiles.add(farg.location); + } + } + assertContainsUnordered("Files/Dirs",expectedFiles,actualFiles); + } + + private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir) + { + String value = baseHome.toShortForm(path); + if (value.startsWith("${")) + { + return value; + } + + if (path.startsWith(testResourcesDir)) + { + int len = testResourcesDir.toString().length(); + value = "${maven-test-resources}" + value.substring(len); + } + return value; + } + + public static void assertContainsUnordered(String msg, Collection expectedSet, Collection actualSet) + { + // same size? + boolean mismatch = expectedSet.size() != actualSet.size(); + + // test content + Set missing = new HashSet<>(); + for (String expected : expectedSet) + { + if (!actualSet.contains(expected)) + { + missing.add(expected); + } + } + + if (mismatch || missing.size() > 0) + { + // build up detailed error message + StringWriter message = new StringWriter(); + PrintWriter err = new PrintWriter(message); + + err.printf("%s: Assert Contains (Unordered)",msg); + if (mismatch) + { + err.print(" [size mismatch]"); + } + if (missing.size() >= 0) + { + err.printf(" [%d entries missing]",missing.size()); + } + err.println(); + err.printf("Actual Entries (size: %d)%n",actualSet.size()); + for (String actual : actualSet) + { + char indicator = expectedSet.contains(actual)?' ':'>'; + err.printf("%s| %s%n",indicator,actual); + } + err.printf("Expected Entries (size: %d)%n",expectedSet.size()); + for (String expected : expectedSet) + { + char indicator = actualSet.contains(expected)?' ':'>'; + err.printf("%s| %s%n",indicator,expected); + } + err.flush(); + Assert.fail(message.toString()); + } + } + + public static void assertOrdered(String msg, List expectedList, List actualList) + { + // same size? + boolean mismatch = expectedList.size() != actualList.size(); + + // test content + List badEntries = new ArrayList<>(); + int min = Math.min(expectedList.size(),actualList.size()); + int max = Math.max(expectedList.size(),actualList.size()); + for (int i = 0; i < min; i++) + { + if (!expectedList.get(i).equals(actualList.get(i))) + { + badEntries.add(i); + } + } + for (int i = min; i < max; i++) + { + badEntries.add(i); + } + + if (mismatch || badEntries.size() > 0) + { + // build up detailed error message + StringWriter message = new StringWriter(); + PrintWriter err = new PrintWriter(message); + + err.printf("%s: Assert Contains (Unordered)",msg); + if (mismatch) + { + err.print(" [size mismatch]"); + } + if (badEntries.size() >= 0) + { + err.printf(" [%d entries not matched]",badEntries.size()); + } + err.println(); + err.printf("Actual Entries (size: %d)%n",actualList.size()); + for (int i = 0; i < actualList.size(); i++) + { + String actual = actualList.get(i); + char indicator = badEntries.contains(i)?'>':' '; + err.printf("%s[%d] %s%n",indicator,i,actual); + } + + err.printf("Expected Entries (size: %d)%n",expectedList.size()); + for (int i = 0; i < expectedList.size(); i++) + { + String expected = expectedList.get(i); + char indicator = badEntries.contains(i)?'>':' '; + err.printf("%s[%d] %s%n",indicator,i,expected); + } + err.flush(); + Assert.fail(message.toString()); + } + } + + private static String getValue(String arg) + { + int idx = arg.indexOf('|'); + Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0)); + String value = arg.substring(idx + 1).trim(); + Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0)); + return value; + } +} From ec273b7cf024cf075c3845ff82f260a6b32fe944 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 3 Apr 2019 19:13:19 +0200 Subject: [PATCH 40/74] Fixes after merge. Signed-off-by: Simone Bordet --- .../jetty/client/AbstractHttpClientServerTest.java | 3 ++- .../jetty/client/TLSServerConnectionCloseTest.java | 1 + .../jetty/fcgi/server/proxy/TryFilesFilterTest.java | 1 + .../test/resources/jetty-websocket-httpclient.xml | 5 +---- .../jetty/http/client/HttpClientLoadTest.java | 13 ++++++++----- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java index 174330da7d7..d5c7218362f 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java @@ -79,9 +79,10 @@ public abstract class AbstractHttpClientServerTest HttpClientTransport transport = new HttpClientTransportOverHTTP(clientConnector); QueuedThreadPool executor = new QueuedThreadPool(); executor.setName("client"); + clientConnector.setExecutor(executor); Scheduler scheduler = new ScheduledExecutorScheduler("client-scheduler", false); + clientConnector.setScheduler(scheduler); client = newHttpClient(transport); - client.setScheduler(scheduler); client.setSocketAddressResolver(new SocketAddressResolver.Sync()); if (config != null) config.accept(client); diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java index 4bee634598d..9568b69eb28 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java @@ -52,6 +52,7 @@ public class TLSServerConnectionCloseTest 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); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java index 63e29ffd6e2..e62eb00ec62 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java @@ -71,6 +71,7 @@ public class TryFilesFilterTest 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"); diff --git a/jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml b/jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml index 5530e171db7..ee97fb070fa 100644 --- a/jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml +++ b/jetty-websocket/javax-websocket-server/src/test/resources/jetty-websocket-httpclient.xml @@ -1,9 +1,6 @@ - - - @@ -18,4 +15,4 @@ - \ No newline at end of file + diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java index 7858edebdc9..570ab405b83 100644 --- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java +++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientLoadTest.java @@ -47,6 +47,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.io.ArrayByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.ClientConnector; import org.eclipse.jetty.io.LeakTrackingByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.server.Connector; @@ -369,9 +370,8 @@ public class HttpClientLoadTest extends AbstractTest new LeakTrackingConnectionPool(destination, client.getMaxConnectionsPerDestination(), destination) { @Override @@ -417,7 +420,7 @@ public class HttpClientLoadTest extends AbstractTest new LeakTrackingConnectionPool(destination, client.getMaxConnectionsPerDestination(), destination) { @Override From a18c2c49f94aba4a32356af438e0cdc4e9a35a96 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 3 Apr 2019 19:24:14 +0200 Subject: [PATCH 41/74] Issue #3464 - Split SslContextFactory into Client and Server Fixed a couple of places where Server was used instead of Client. Signed-off-by: Simone Bordet --- .../client/TLSServerConnectionCloseTest.java | 3 ++- .../fcgi/server/proxy/TryFilesFilterTest.java | 18 +++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java index e31911f32c2..6108be5346b 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java @@ -48,7 +48,8 @@ public class TLSServerConnectionCloseTest private void startClient() throws Exception { - SslContextFactory sslContextFactory = new SslContextFactory.Server(); + SslContextFactory sslContextFactory = new SslContextFactory.Client(); + sslContextFactory.setEndpointIdentificationAlgorithm(null); sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks"); sslContextFactory.setKeyStorePassword("storepwd"); diff --git a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java index afbb714dfaa..6df8d40f8c2 100644 --- a/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java +++ b/jetty-fcgi/fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/proxy/TryFilesFilterTest.java @@ -55,12 +55,10 @@ public class TryFilesFilterTest connector = new ServerConnector(server); server.addConnector(connector); - SslContextFactory sslContextFactory = new SslContextFactory.Server(); - 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, "/"); @@ -71,7 +69,13 @@ public class TryFilesFilterTest context.addServlet(new ServletHolder(servlet), "/*"); - client = new HttpClient(sslContextFactory); + 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"); + client = new HttpClient(clientSslContextFactory); server.addBean(client); server.start(); From 1f046f44fea0e0c0139188882512fcafbc80e15f Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 3 Apr 2019 15:24:29 -0500 Subject: [PATCH 42/74] Fixing CRLF issues. Signed-off-by: Joakim Erdfelt --- .../jetty/http/spi/HttpSpiContextHandler.java | 324 +++++----- .../jetty/http/spi/JettyHttpContext.java | 222 +++---- .../http/spi/JettyHttpExchangeDelegate.java | 466 +++++++-------- .../http/spi/JettyHttpServerProvider.java | 160 ++--- .../jetty/maven/plugin/JettyDeployWar.java | 162 ++--- .../jetty/security/AliasedConstraintTest.java | 348 +++++------ .../org/eclipse/jetty/start/BaseHomeTest.java | 422 ++++++------- .../jetty/start/ConfigurationAssert.java | 562 +++++++++--------- 8 files changed, 1333 insertions(+), 1333 deletions(-) diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java index 2713682899d..7ba6bdaf626 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java @@ -1,162 +1,162 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.Authenticator.Result; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpPrincipal; - -/** - * Jetty handler that bridges requests to {@link HttpHandler}. - */ -public class HttpSpiContextHandler extends ContextHandler -{ - public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class); - - private HttpContext _httpContext; - - private HttpHandler _httpHandler; - - public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler) - { - this._httpContext = httpContext; - this._httpHandler = httpHandler; - } - - @Override - public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException - { - if (!target.startsWith(getContextPath())) - { - return; - } - - HttpExchange jettyHttpExchange; - if (baseRequest.isSecure()) - { - jettyHttpExchange = new JettyHttpsExchange(_httpContext,req,resp); - } - else - { - jettyHttpExchange = new JettyHttpExchange(_httpContext,req,resp); - } - - // TODO: add filters processing - - try - { - Authenticator auth = _httpContext.getAuthenticator(); - if (auth != null) - { - handleAuthentication(resp,jettyHttpExchange,auth); - } - else - { - _httpHandler.handle(jettyHttpExchange); - } - } - catch (Exception ex) - { - LOG.debug(ex); - PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody()); - - resp.setStatus(500); - writer.println("

HTTP ERROR: 500

"); - writer.println("
INTERNAL_SERVER_ERROR
"); - writer.println("

RequestURI=" + StringUtil.sanitizeXmlString(req.getRequestURI()) + "

"); - - if (LOG.isDebugEnabled()) - { - writer.println("
");
-                ex.printStackTrace(writer);
-                writer.println("
"); - } - - writer.println("

Powered by jetty://

"); - - writer.close(); - } - finally - { - baseRequest.setHandled(true); - } - - } - - private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException - { - Result result = auth.authenticate(httpExchange); - if (result instanceof Authenticator.Failure) - { - int rc = ((Authenticator.Failure)result).getResponseCode(); - for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) - { - for (String value : header.getValue()) - resp.addHeader(header.getKey(),value); - } - resp.sendError(rc); - } - else if (result instanceof Authenticator.Retry) - { - int rc = ((Authenticator.Retry)result).getResponseCode(); - for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) - { - for (String value : header.getValue()) - resp.addHeader(header.getKey(),value); - } - resp.setStatus(rc); - resp.flushBuffer(); - } - else if (result instanceof Authenticator.Success) - { - HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal(); - ((JettyExchange)httpExchange).setPrincipal(principal); - _httpHandler.handle(httpExchange); - } - } - - public HttpHandler getHttpHandler() - { - return _httpHandler; - } - - public void setHttpHandler(HttpHandler handler) - { - this._httpHandler = handler; - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.Authenticator.Result; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpPrincipal; + +/** + * Jetty handler that bridges requests to {@link HttpHandler}. + */ +public class HttpSpiContextHandler extends ContextHandler +{ + public static final Logger LOG = Log.getLogger(HttpSpiContextHandler.class); + + private HttpContext _httpContext; + + private HttpHandler _httpHandler; + + public HttpSpiContextHandler(HttpContext httpContext, HttpHandler httpHandler) + { + this._httpContext = httpContext; + this._httpHandler = httpHandler; + } + + @Override + public void doScope(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException + { + if (!target.startsWith(getContextPath())) + { + return; + } + + HttpExchange jettyHttpExchange; + if (baseRequest.isSecure()) + { + jettyHttpExchange = new JettyHttpsExchange(_httpContext,req,resp); + } + else + { + jettyHttpExchange = new JettyHttpExchange(_httpContext,req,resp); + } + + // TODO: add filters processing + + try + { + Authenticator auth = _httpContext.getAuthenticator(); + if (auth != null) + { + handleAuthentication(resp,jettyHttpExchange,auth); + } + else + { + _httpHandler.handle(jettyHttpExchange); + } + } + catch (Exception ex) + { + LOG.debug(ex); + PrintWriter writer = new PrintWriter(jettyHttpExchange.getResponseBody()); + + resp.setStatus(500); + writer.println("

HTTP ERROR: 500

"); + writer.println("
INTERNAL_SERVER_ERROR
"); + writer.println("

RequestURI=" + StringUtil.sanitizeXmlString(req.getRequestURI()) + "

"); + + if (LOG.isDebugEnabled()) + { + writer.println("
");
+                ex.printStackTrace(writer);
+                writer.println("
"); + } + + writer.println("

Powered by jetty://

"); + + writer.close(); + } + finally + { + baseRequest.setHandled(true); + } + + } + + private void handleAuthentication(HttpServletResponse resp, HttpExchange httpExchange, Authenticator auth) throws IOException + { + Result result = auth.authenticate(httpExchange); + if (result instanceof Authenticator.Failure) + { + int rc = ((Authenticator.Failure)result).getResponseCode(); + for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) + { + for (String value : header.getValue()) + resp.addHeader(header.getKey(),value); + } + resp.sendError(rc); + } + else if (result instanceof Authenticator.Retry) + { + int rc = ((Authenticator.Retry)result).getResponseCode(); + for (Map.Entry> header : httpExchange.getResponseHeaders().entrySet()) + { + for (String value : header.getValue()) + resp.addHeader(header.getKey(),value); + } + resp.setStatus(rc); + resp.flushBuffer(); + } + else if (result instanceof Authenticator.Success) + { + HttpPrincipal principal = ((Authenticator.Success)result).getPrincipal(); + ((JettyExchange)httpExchange).setPrincipal(principal); + _httpHandler.handle(httpExchange); + } + } + + public HttpHandler getHttpHandler() + { + return _httpHandler; + } + + public void setHttpHandler(HttpHandler handler) + { + this._httpHandler = handler; + } + +} diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java index 39d2285addb..18b45d99ea5 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java @@ -1,111 +1,111 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.sun.net.httpserver.Authenticator; -import com.sun.net.httpserver.Filter; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; - -/** - * Jetty implementation of {@link com.sun.net.httpserver.HttpContext} - */ -public class JettyHttpContext extends com.sun.net.httpserver.HttpContext -{ - - private HttpSpiContextHandler _jettyContextHandler; - - private HttpServer _server; - - private Map _attributes = new HashMap(); - - private List _filters = new ArrayList(); - - private Authenticator _authenticator; - - - protected JettyHttpContext(HttpServer server, String path, - HttpHandler handler) - { - this._server = server; - _jettyContextHandler = new HttpSpiContextHandler(this, handler); - _jettyContextHandler.setContextPath(path); - } - - protected HttpSpiContextHandler getJettyContextHandler() - { - return _jettyContextHandler; - } - - @Override - public HttpHandler getHandler() - { - return _jettyContextHandler.getHttpHandler(); - } - - @Override - public void setHandler(HttpHandler h) - { - _jettyContextHandler.setHttpHandler(h); - } - - @Override - public String getPath() - { - return _jettyContextHandler.getContextPath(); - } - - @Override - public HttpServer getServer() - { - return _server; - } - - @Override - public Map getAttributes() - { - return _attributes; - } - - @Override - public List getFilters() - { - return _filters; - } - - @Override - public Authenticator setAuthenticator(Authenticator auth) - { - Authenticator previous = _authenticator; - _authenticator = auth; - return previous; - } - - @Override - public Authenticator getAuthenticator() - { - return _authenticator; - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.sun.net.httpserver.Authenticator; +import com.sun.net.httpserver.Filter; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +/** + * Jetty implementation of {@link com.sun.net.httpserver.HttpContext} + */ +public class JettyHttpContext extends com.sun.net.httpserver.HttpContext +{ + + private HttpSpiContextHandler _jettyContextHandler; + + private HttpServer _server; + + private Map _attributes = new HashMap(); + + private List _filters = new ArrayList(); + + private Authenticator _authenticator; + + + protected JettyHttpContext(HttpServer server, String path, + HttpHandler handler) + { + this._server = server; + _jettyContextHandler = new HttpSpiContextHandler(this, handler); + _jettyContextHandler.setContextPath(path); + } + + protected HttpSpiContextHandler getJettyContextHandler() + { + return _jettyContextHandler; + } + + @Override + public HttpHandler getHandler() + { + return _jettyContextHandler.getHttpHandler(); + } + + @Override + public void setHandler(HttpHandler h) + { + _jettyContextHandler.setHttpHandler(h); + } + + @Override + public String getPath() + { + return _jettyContextHandler.getContextPath(); + } + + @Override + public HttpServer getServer() + { + return _server; + } + + @Override + public Map getAttributes() + { + return _attributes; + } + + @Override + public List getFilters() + { + return _filters; + } + + @Override + public Authenticator setAuthenticator(Authenticator auth) + { + Authenticator previous = _authenticator; + _authenticator = auth; + return previous; + } + + @Override + public Authenticator getAuthenticator() + { + return _authenticator; + } + +} diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java index 8d5d3afb0c0..556efbc81ce 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java @@ -1,233 +1,233 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpContext; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpPrincipal; - -/** - * Jetty implementation of {@link com.sun.net.httpserver.HttpExchange} - */ -public class JettyHttpExchangeDelegate extends HttpExchange -{ - - private HttpContext _httpContext; - - private HttpServletRequest _req; - - private HttpServletResponse _resp; - - private Headers _responseHeaders = new Headers(); - - private int _responseCode = 0; - - private InputStream _is; - - private OutputStream _os; - - private HttpPrincipal _httpPrincipal; - - JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp) - { - this._httpContext = jaxWsContext; - this._req = req; - this._resp = resp; - try - { - this._is = req.getInputStream(); - this._os = resp.getOutputStream(); - } - catch (IOException ex) - { - throw new RuntimeException(ex); - } - } - - @Override - public Headers getRequestHeaders() - { - Headers headers = new Headers(); - Enumeration en = _req.getHeaderNames(); - while (en.hasMoreElements()) - { - String name = (String)en.nextElement(); - Enumeration en2 = _req.getHeaders(name); - while (en2.hasMoreElements()) - { - String value = (String)en2.nextElement(); - headers.add(name,value); - } - } - return headers; - } - - @Override - public Headers getResponseHeaders() - { - return _responseHeaders; - } - - @Override - public URI getRequestURI() - { - try - { - String uriAsString = _req.getRequestURI(); - if (_req.getQueryString() != null) - { - uriAsString += "?" + _req.getQueryString(); - } - - return new URI(uriAsString); - } - catch (URISyntaxException ex) - { - throw new RuntimeException(ex); - } - } - - @Override - public String getRequestMethod() - { - return _req.getMethod(); - } - - @Override - public HttpContext getHttpContext() - { - return _httpContext; - } - - @Override - public void close() - { - try - { - _resp.getOutputStream().close(); - } - catch (IOException ex) - { - throw new RuntimeException(ex); - } - } - - @Override - public InputStream getRequestBody() - { - return _is; - } - - @Override - public OutputStream getResponseBody() - { - return _os; - } - - @Override - public void sendResponseHeaders(int rCode, long responseLength) throws IOException - { - this._responseCode = rCode; - - for (Map.Entry> stringListEntry : _responseHeaders.entrySet()) - { - String name = stringListEntry.getKey(); - List values = stringListEntry.getValue(); - - for (String value : values) - { - _resp.setHeader(name,value); - } - } - if (responseLength > 0) - { - _resp.setHeader("content-length","" + responseLength); - } - _resp.setStatus(rCode); - } - - @Override - public InetSocketAddress getRemoteAddress() - { - return new InetSocketAddress(_req.getRemoteAddr(),_req.getRemotePort()); - } - - @Override - public int getResponseCode() - { - return _responseCode; - } - - @Override - public InetSocketAddress getLocalAddress() - { - return new InetSocketAddress(_req.getLocalAddr(),_req.getLocalPort()); - } - - @Override - public String getProtocol() - { - return _req.getProtocol(); - } - - @Override - public Object getAttribute(String name) - { - return _req.getAttribute(name); - } - - @Override - public void setAttribute(String name, Object value) - { - _req.setAttribute(name,value); - } - - @Override - public void setStreams(InputStream i, OutputStream o) - { - _is = i; - _os = o; - } - - @Override - public HttpPrincipal getPrincipal() - { - return _httpPrincipal; - } - - public void setPrincipal(HttpPrincipal principal) - { - this._httpPrincipal = principal; - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpPrincipal; + +/** + * Jetty implementation of {@link com.sun.net.httpserver.HttpExchange} + */ +public class JettyHttpExchangeDelegate extends HttpExchange +{ + + private HttpContext _httpContext; + + private HttpServletRequest _req; + + private HttpServletResponse _resp; + + private Headers _responseHeaders = new Headers(); + + private int _responseCode = 0; + + private InputStream _is; + + private OutputStream _os; + + private HttpPrincipal _httpPrincipal; + + JettyHttpExchangeDelegate(HttpContext jaxWsContext, HttpServletRequest req, HttpServletResponse resp) + { + this._httpContext = jaxWsContext; + this._req = req; + this._resp = resp; + try + { + this._is = req.getInputStream(); + this._os = resp.getOutputStream(); + } + catch (IOException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public Headers getRequestHeaders() + { + Headers headers = new Headers(); + Enumeration en = _req.getHeaderNames(); + while (en.hasMoreElements()) + { + String name = (String)en.nextElement(); + Enumeration en2 = _req.getHeaders(name); + while (en2.hasMoreElements()) + { + String value = (String)en2.nextElement(); + headers.add(name,value); + } + } + return headers; + } + + @Override + public Headers getResponseHeaders() + { + return _responseHeaders; + } + + @Override + public URI getRequestURI() + { + try + { + String uriAsString = _req.getRequestURI(); + if (_req.getQueryString() != null) + { + uriAsString += "?" + _req.getQueryString(); + } + + return new URI(uriAsString); + } + catch (URISyntaxException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public String getRequestMethod() + { + return _req.getMethod(); + } + + @Override + public HttpContext getHttpContext() + { + return _httpContext; + } + + @Override + public void close() + { + try + { + _resp.getOutputStream().close(); + } + catch (IOException ex) + { + throw new RuntimeException(ex); + } + } + + @Override + public InputStream getRequestBody() + { + return _is; + } + + @Override + public OutputStream getResponseBody() + { + return _os; + } + + @Override + public void sendResponseHeaders(int rCode, long responseLength) throws IOException + { + this._responseCode = rCode; + + for (Map.Entry> stringListEntry : _responseHeaders.entrySet()) + { + String name = stringListEntry.getKey(); + List values = stringListEntry.getValue(); + + for (String value : values) + { + _resp.setHeader(name,value); + } + } + if (responseLength > 0) + { + _resp.setHeader("content-length","" + responseLength); + } + _resp.setStatus(rCode); + } + + @Override + public InetSocketAddress getRemoteAddress() + { + return new InetSocketAddress(_req.getRemoteAddr(),_req.getRemotePort()); + } + + @Override + public int getResponseCode() + { + return _responseCode; + } + + @Override + public InetSocketAddress getLocalAddress() + { + return new InetSocketAddress(_req.getLocalAddr(),_req.getLocalPort()); + } + + @Override + public String getProtocol() + { + return _req.getProtocol(); + } + + @Override + public Object getAttribute(String name) + { + return _req.getAttribute(name); + } + + @Override + public void setAttribute(String name, Object value) + { + _req.setAttribute(name,value); + } + + @Override + public void setStreams(InputStream i, OutputStream o) + { + _is = i; + _os = o; + } + + @Override + public HttpPrincipal getPrincipal() + { + return _httpPrincipal; + } + + public void setPrincipal(HttpPrincipal principal) + { + this._httpPrincipal = principal; + } + +} diff --git a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java index 65acd613e3b..eb5f07eca92 100644 --- a/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java +++ b/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java @@ -1,80 +1,80 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http.spi; - -import java.io.IOException; -import java.net.InetSocketAddress; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.server.handler.DefaultHandler; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.eclipse.jetty.util.thread.ThreadPool; - -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsServer; -import com.sun.net.httpserver.spi.HttpServerProvider; - -/** - * Jetty implementation of Java HTTP Server SPI - */ -public class JettyHttpServerProvider extends HttpServerProvider -{ - - private static Server _server; - - public static void setServer(Server server) - { - _server = server; - } - - @Override - public HttpServer createHttpServer(InetSocketAddress addr, int backlog) - throws IOException - { - Server server = _server; - boolean shared = true; - - if (server == null) - { - ThreadPool threadPool = new DelegatingThreadPool(new QueuedThreadPool()); - server = new Server(threadPool); - - HandlerCollection handlerCollection = new HandlerCollection(); - handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()}); - server.setHandler(handlerCollection); - - shared = false; - } - - JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared); - if (addr != null) - jettyHttpServer.bind(addr, backlog); - return jettyHttpServer; - } - - @Override - public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException - { - throw new UnsupportedOperationException(); - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http.spi; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.server.handler.DefaultHandler; +import org.eclipse.jetty.server.handler.HandlerCollection; +import org.eclipse.jetty.util.thread.QueuedThreadPool; +import org.eclipse.jetty.util.thread.ThreadPool; + +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpsServer; +import com.sun.net.httpserver.spi.HttpServerProvider; + +/** + * Jetty implementation of Java HTTP Server SPI + */ +public class JettyHttpServerProvider extends HttpServerProvider +{ + + private static Server _server; + + public static void setServer(Server server) + { + _server = server; + } + + @Override + public HttpServer createHttpServer(InetSocketAddress addr, int backlog) + throws IOException + { + Server server = _server; + boolean shared = true; + + if (server == null) + { + ThreadPool threadPool = new DelegatingThreadPool(new QueuedThreadPool()); + server = new Server(threadPool); + + HandlerCollection handlerCollection = new HandlerCollection(); + handlerCollection.setHandlers(new Handler[] {new ContextHandlerCollection(), new DefaultHandler()}); + server.setHandler(handlerCollection); + + shared = false; + } + + JettyHttpServer jettyHttpServer = new JettyHttpServer(server, shared); + if (addr != null) + jettyHttpServer.bind(addr, backlog); + return jettyHttpServer; + } + + @Override + public HttpsServer createHttpsServer(InetSocketAddress addr, int backlog) throws IOException + { + throw new UnsupportedOperationException(); + } + +} diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java index 285d8d85e60..5b075511452 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyDeployWar.java @@ -1,81 +1,81 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.maven.plugin; - -import java.io.File; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; - -/** - *

- * This goal is used to run Jetty with a pre-assembled war. - *

- *

- * It accepts exactly the same options as the run-war goal. - * However, it doesn't assume that the current artifact is a - * webapp and doesn't try to assemble it into a war before its execution. - * So using it makes sense only when used in conjunction with the - * war configuration parameter pointing to a pre-built WAR. - *

- *

- * This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested - * HTTP client components. - *

- * - * @goal deploy-war - * @requiresDependencyResolution runtime - * @execute phase="validate" - * @description Deploy a pre-assembled war - * - */ -public class JettyDeployWar extends JettyRunWarMojo -{ - - - /** - * If true, the plugin should continue and not block. Otherwise the - * plugin will block further execution and you will need to use - * cntrl-c to stop it. - * - * - * @parameter default-value="true" - */ - protected boolean daemon = true; - - - @Override - public void execute() throws MojoExecutionException, MojoFailureException - { - nonblocking = daemon; - super.execute(); - } - - - - @Override - public void finishConfigurationBeforeStart() throws Exception - { - super.finishConfigurationBeforeStart(); - //only stop the server at shutdown if we are blocking - server.setStopAtShutdown(!nonblocking); - - } - -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.maven.plugin; + +import java.io.File; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + *

+ * This goal is used to run Jetty with a pre-assembled war. + *

+ *

+ * It accepts exactly the same options as the run-war goal. + * However, it doesn't assume that the current artifact is a + * webapp and doesn't try to assemble it into a war before its execution. + * So using it makes sense only when used in conjunction with the + * war configuration parameter pointing to a pre-built WAR. + *

+ *

+ * This goal is useful e.g. for launching a web app in Jetty as a target for unit-tested + * HTTP client components. + *

+ * + * @goal deploy-war + * @requiresDependencyResolution runtime + * @execute phase="validate" + * @description Deploy a pre-assembled war + * + */ +public class JettyDeployWar extends JettyRunWarMojo +{ + + + /** + * If true, the plugin should continue and not block. Otherwise the + * plugin will block further execution and you will need to use + * cntrl-c to stop it. + * + * + * @parameter default-value="true" + */ + protected boolean daemon = true; + + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + nonblocking = daemon; + super.execute(); + } + + + + @Override + public void finishConfigurationBeforeStart() throws Exception + { + super.finishConfigurationBeforeStart(); + //only stop the server at shutdown if we are blocking + server.setStopAtShutdown(!nonblocking); + + } + +} diff --git a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java index 00161f1125c..1ef2704f37a 100644 --- a/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java +++ b/jetty-security/src/test/java/org/eclipse/jetty/security/AliasedConstraintTest.java @@ -1,174 +1,174 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.LocalConnector; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.ResourceHandler; -import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.util.security.Password; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - -/** - * Some requests for static data that is served by ResourceHandler, but some is secured. - *

- * This is mainly here to test security bypass techniques using aliased names that should be caught. - */ -@RunWith(Parameterized.class) -public class AliasedConstraintTest -{ - private static final String TEST_REALM = "TestRealm"; - private static Server server; - private static LocalConnector connector; - private static ConstraintSecurityHandler security; - - @BeforeClass - public static void startServer() throws Exception - { - server = new Server(); - connector = new LocalConnector(server); - server.setConnectors(new Connector[] { connector }); - - ContextHandler context = new ContextHandler(); - SessionHandler session = new SessionHandler(); - - HashLoginService loginService = new HashLoginService(TEST_REALM); - loginService.putUser("user0",new Password("password"),new String[] {}); - loginService.putUser("user",new Password("password"),new String[] { "user" }); - loginService.putUser("user2",new Password("password"),new String[] { "user" }); - loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" }); - loginService.putUser("user3",new Password("password"),new String[] { "foo" }); - - context.setContextPath("/ctx"); - context.setResourceBase(MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath()); - server.setHandler(context); - context.setHandler(session); - // context.addAliasCheck(new AllowSymLinkAliasChecker()); - - server.addBean(loginService); - - security = new ConstraintSecurityHandler(); - session.setHandler(security); - ResourceHandler handler = new ResourceHandler(); - security.setHandler(handler); - - List constraints = new ArrayList<>(); - - Constraint constraint0 = new Constraint(); - constraint0.setAuthenticate(true); - constraint0.setName("forbid"); - ConstraintMapping mapping0 = new ConstraintMapping(); - mapping0.setPathSpec("/forbid/*"); - mapping0.setConstraint(constraint0); - constraints.add(mapping0); - - Set knownRoles = new HashSet<>(); - knownRoles.add("user"); - knownRoles.add("administrator"); - - security.setConstraintMappings(constraints,knownRoles); - server.start(); - } - - @AfterClass - public static void stopServer() throws Exception - { - server.stop(); - } - - @Parameters(name = "{0}: {1}") - public static Collection data() - { - List data = new ArrayList<>(); - - final String OPENCONTENT = "this is open content"; - - data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); - data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null }); - data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null }); - data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); - data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); - data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); - data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null }); - - return data; - } - - @Parameter(value = 0) - public String uri; - - @Parameter(value = 1) - public int expectedStatusCode; - - @Parameter(value = 2) - public String expectedContent; - - @Test - public void testAccess() throws Exception - { - StringBuilder request = new StringBuilder(); - request.append("GET ").append(uri).append(" HTTP/1.1\r\n"); - request.append("Host: localhost\r\n"); - request.append("Connection: close\r\n"); - request.append("\r\n"); - - String response = connector.getResponses(request.toString()); - - switch (expectedStatusCode) - { - case 200: - assertThat(response,startsWith("HTTP/1.1 200 OK")); - break; - case 403: - assertThat(response,startsWith("HTTP/1.1 403 Forbidden")); - break; - case 404: - assertThat(response,startsWith("HTTP/1.1 404 Not Found")); - break; - default: - fail("Write a handler for response status code: " + expectedStatusCode); - break; - } - - if (expectedContent != null) - { - assertThat(response,containsString("this is open content")); - } - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ResourceHandler; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Password; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** + * Some requests for static data that is served by ResourceHandler, but some is secured. + *

+ * This is mainly here to test security bypass techniques using aliased names that should be caught. + */ +@RunWith(Parameterized.class) +public class AliasedConstraintTest +{ + private static final String TEST_REALM = "TestRealm"; + private static Server server; + private static LocalConnector connector; + private static ConstraintSecurityHandler security; + + @BeforeClass + public static void startServer() throws Exception + { + server = new Server(); + connector = new LocalConnector(server); + server.setConnectors(new Connector[] { connector }); + + ContextHandler context = new ContextHandler(); + SessionHandler session = new SessionHandler(); + + HashLoginService loginService = new HashLoginService(TEST_REALM); + loginService.putUser("user0",new Password("password"),new String[] {}); + loginService.putUser("user",new Password("password"),new String[] { "user" }); + loginService.putUser("user2",new Password("password"),new String[] { "user" }); + loginService.putUser("admin",new Password("password"),new String[] { "user", "administrator" }); + loginService.putUser("user3",new Password("password"),new String[] { "foo" }); + + context.setContextPath("/ctx"); + context.setResourceBase(MavenTestingUtils.getTestResourceDir("docroot").getAbsolutePath()); + server.setHandler(context); + context.setHandler(session); + // context.addAliasCheck(new AllowSymLinkAliasChecker()); + + server.addBean(loginService); + + security = new ConstraintSecurityHandler(); + session.setHandler(security); + ResourceHandler handler = new ResourceHandler(); + security.setHandler(handler); + + List constraints = new ArrayList<>(); + + Constraint constraint0 = new Constraint(); + constraint0.setAuthenticate(true); + constraint0.setName("forbid"); + ConstraintMapping mapping0 = new ConstraintMapping(); + mapping0.setPathSpec("/forbid/*"); + mapping0.setConstraint(constraint0); + constraints.add(mapping0); + + Set knownRoles = new HashSet<>(); + knownRoles.add("user"); + knownRoles.add("administrator"); + + security.setConstraintMappings(constraints,knownRoles); + server.start(); + } + + @AfterClass + public static void stopServer() throws Exception + { + server.stop(); + } + + @Parameters(name = "{0}: {1}") + public static Collection data() + { + List data = new ArrayList<>(); + + final String OPENCONTENT = "this is open content"; + + data.add(new Object[] { "/ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); + data.add(new Object[] { "/ctx/ALL/index.txt", HttpStatus.NOT_FOUND_404, null }); + data.add(new Object[] { "/ctx/ALL/Fred/../index.txt", HttpStatus.NOT_FOUND_404, null }); + data.add(new Object[] { "/ctx/../bar/../ctx/all/index.txt", HttpStatus.OK_200, OPENCONTENT }); + data.add(new Object[] { "/ctx/forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); + data.add(new Object[] { "/ctx/all/../forbid/index.txt", HttpStatus.FORBIDDEN_403, null }); + data.add(new Object[] { "/ctx/FoRbId/index.txt", HttpStatus.NOT_FOUND_404, null }); + + return data; + } + + @Parameter(value = 0) + public String uri; + + @Parameter(value = 1) + public int expectedStatusCode; + + @Parameter(value = 2) + public String expectedContent; + + @Test + public void testAccess() throws Exception + { + StringBuilder request = new StringBuilder(); + request.append("GET ").append(uri).append(" HTTP/1.1\r\n"); + request.append("Host: localhost\r\n"); + request.append("Connection: close\r\n"); + request.append("\r\n"); + + String response = connector.getResponses(request.toString()); + + switch (expectedStatusCode) + { + case 200: + assertThat(response,startsWith("HTTP/1.1 200 OK")); + break; + case 403: + assertThat(response,startsWith("HTTP/1.1 403 Forbidden")); + break; + case 404: + assertThat(response,startsWith("HTTP/1.1 404 Not Found")); + break; + default: + fail("Write a handler for response status code: " + expectedStatusCode); + break; + } + + if (expectedContent != null) + { + assertThat(response,containsString("this is open content")); + } + } +} diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java index 2166e7ce8c5..d4873795bab 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java @@ -1,211 +1,211 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.start; - -import static org.hamcrest.Matchers.*; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jetty.start.config.ConfigSources; -import org.eclipse.jetty.start.config.JettyBaseConfigSource; -import org.eclipse.jetty.start.config.JettyHomeConfigSource; -import org.eclipse.jetty.toolchain.test.IO; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.junit.Assert; -import org.junit.Test; - -public class BaseHomeTest -{ - public static void assertPathList(BaseHome hb, String message, List expected, PathFinder finder) - { - List actual = new ArrayList<>(); - for (Path path : finder.getHits()) - { - actual.add(hb.toShortForm(path.toFile())); - } - - if (actual.size() != expected.size()) - { - System.out.printf("Actual Path(s): %,d hits%n",actual.size()); - for (String path : actual) - { - System.out.printf(" %s%n",path); - } - System.out.printf("Expected Path(s): %,d entries%n",expected.size()); - for (String path : expected) - { - System.out.printf(" %s%n",path); - } - } - Assert.assertThat(message + ": " + Main.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); - } - - public static void assertPathList(BaseHome hb, String message, List expected, List paths) - { - List actual = new ArrayList<>(); - for (Path path : paths) - { - actual.add(hb.toShortForm(path.toFile())); - } - - if (actual.size() != expected.size()) - { - System.out.printf("Actual Path(s): %,d hits%n",actual.size()); - for (String path : actual) - { - System.out.printf(" %s%n",path); - } - System.out.printf("Expected Path(s): %,d entries%n",expected.size()); - for (String path : expected) - { - System.out.printf(" %s%n",path); - } - } - Assert.assertThat(message + ": " + Main.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); - } - - public static void assertFileList(BaseHome hb, String message, List expected, List files) - { - List actual = new ArrayList<>(); - for (File file : files) - { - actual.add(hb.toShortForm(file)); - } - Assert.assertThat(message + ": " + Main.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); - } - - @Test - public void testGetPath_OnlyHome() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - Path startIni = hb.getPath("start.ini"); - - String ref = hb.toShortForm(startIni); - Assert.assertThat("Reference",ref,startsWith("${jetty.home}")); - - String contents = IO.readToString(startIni.toFile()); - Assert.assertThat("Contents",contents,containsString("Home Ini")); - } - - @Test - public void testGetPaths_OnlyHome() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - List paths = hb.getPaths("start.d/*"); - - List expected = new ArrayList<>(); - expected.add("${jetty.home}/start.d/jmx.ini"); - expected.add("${jetty.home}/start.d/jndi.ini"); - expected.add("${jetty.home}/start.d/jsp.ini"); - expected.add("${jetty.home}/start.d/logging.ini"); - expected.add("${jetty.home}/start.d/ssl.ini"); - FSTest.toOsSeparators(expected); - - assertPathList(hb,"Paths found",expected,paths); - } - - @Test - public void testGetPaths_OnlyHome_InisOnly() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - List paths = hb.getPaths("start.d/*.ini"); - - List expected = new ArrayList<>(); - expected.add("${jetty.home}/start.d/jmx.ini"); - expected.add("${jetty.home}/start.d/jndi.ini"); - expected.add("${jetty.home}/start.d/jsp.ini"); - expected.add("${jetty.home}/start.d/logging.ini"); - expected.add("${jetty.home}/start.d/ssl.ini"); - FSTest.toOsSeparators(expected); - - assertPathList(hb,"Paths found",expected,paths); - } - - @Test - public void testGetPaths_Both() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyBaseConfigSource(baseDir.toPath())); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - List paths = hb.getPaths("start.d/*.ini"); - - List expected = new ArrayList<>(); - expected.add("${jetty.base}/start.d/jmx.ini"); - expected.add("${jetty.home}/start.d/jndi.ini"); - expected.add("${jetty.home}/start.d/jsp.ini"); - expected.add("${jetty.base}/start.d/logging.ini"); - expected.add("${jetty.home}/start.d/ssl.ini"); - expected.add("${jetty.base}/start.d/myapp.ini"); - FSTest.toOsSeparators(expected); - - assertPathList(hb,"Paths found",expected,paths); - } - - @Test - public void testDefault() throws IOException - { - BaseHome bh = new BaseHome(); - Assert.assertThat("Home",bh.getHome(),notNullValue()); - Assert.assertThat("Base",bh.getBase(),notNullValue()); - } - - @Test - public void testGetPath_Both() throws IOException - { - File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); - File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); - - ConfigSources config = new ConfigSources(); - config.add(new JettyBaseConfigSource(baseDir.toPath())); - config.add(new JettyHomeConfigSource(homeDir.toPath())); - - BaseHome hb = new BaseHome(config); - Path startIni = hb.getPath("start.ini"); - - String ref = hb.toShortForm(startIni); - Assert.assertThat("Reference",ref,startsWith("${jetty.base}")); - - String contents = IO.readToString(startIni.toFile()); - Assert.assertThat("Contents",contents,containsString("Base Ini")); - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.start; + +import static org.hamcrest.Matchers.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jetty.start.config.ConfigSources; +import org.eclipse.jetty.start.config.JettyBaseConfigSource; +import org.eclipse.jetty.start.config.JettyHomeConfigSource; +import org.eclipse.jetty.toolchain.test.IO; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Assert; +import org.junit.Test; + +public class BaseHomeTest +{ + public static void assertPathList(BaseHome hb, String message, List expected, PathFinder finder) + { + List actual = new ArrayList<>(); + for (Path path : finder.getHits()) + { + actual.add(hb.toShortForm(path.toFile())); + } + + if (actual.size() != expected.size()) + { + System.out.printf("Actual Path(s): %,d hits%n",actual.size()); + for (String path : actual) + { + System.out.printf(" %s%n",path); + } + System.out.printf("Expected Path(s): %,d entries%n",expected.size()); + for (String path : expected) + { + System.out.printf(" %s%n",path); + } + } + Assert.assertThat(message + ": " + Main.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); + } + + public static void assertPathList(BaseHome hb, String message, List expected, List paths) + { + List actual = new ArrayList<>(); + for (Path path : paths) + { + actual.add(hb.toShortForm(path.toFile())); + } + + if (actual.size() != expected.size()) + { + System.out.printf("Actual Path(s): %,d hits%n",actual.size()); + for (String path : actual) + { + System.out.printf(" %s%n",path); + } + System.out.printf("Expected Path(s): %,d entries%n",expected.size()); + for (String path : expected) + { + System.out.printf(" %s%n",path); + } + } + Assert.assertThat(message + ": " + Main.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); + } + + public static void assertFileList(BaseHome hb, String message, List expected, List files) + { + List actual = new ArrayList<>(); + for (File file : files) + { + actual.add(hb.toShortForm(file)); + } + Assert.assertThat(message + ": " + Main.join(actual,", "),actual,containsInAnyOrder(expected.toArray())); + } + + @Test + public void testGetPath_OnlyHome() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + Path startIni = hb.getPath("start.ini"); + + String ref = hb.toShortForm(startIni); + Assert.assertThat("Reference",ref,startsWith("${jetty.home}")); + + String contents = IO.readToString(startIni.toFile()); + Assert.assertThat("Contents",contents,containsString("Home Ini")); + } + + @Test + public void testGetPaths_OnlyHome() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + List paths = hb.getPaths("start.d/*"); + + List expected = new ArrayList<>(); + expected.add("${jetty.home}/start.d/jmx.ini"); + expected.add("${jetty.home}/start.d/jndi.ini"); + expected.add("${jetty.home}/start.d/jsp.ini"); + expected.add("${jetty.home}/start.d/logging.ini"); + expected.add("${jetty.home}/start.d/ssl.ini"); + FSTest.toOsSeparators(expected); + + assertPathList(hb,"Paths found",expected,paths); + } + + @Test + public void testGetPaths_OnlyHome_InisOnly() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + List paths = hb.getPaths("start.d/*.ini"); + + List expected = new ArrayList<>(); + expected.add("${jetty.home}/start.d/jmx.ini"); + expected.add("${jetty.home}/start.d/jndi.ini"); + expected.add("${jetty.home}/start.d/jsp.ini"); + expected.add("${jetty.home}/start.d/logging.ini"); + expected.add("${jetty.home}/start.d/ssl.ini"); + FSTest.toOsSeparators(expected); + + assertPathList(hb,"Paths found",expected,paths); + } + + @Test + public void testGetPaths_Both() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyBaseConfigSource(baseDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + List paths = hb.getPaths("start.d/*.ini"); + + List expected = new ArrayList<>(); + expected.add("${jetty.base}/start.d/jmx.ini"); + expected.add("${jetty.home}/start.d/jndi.ini"); + expected.add("${jetty.home}/start.d/jsp.ini"); + expected.add("${jetty.base}/start.d/logging.ini"); + expected.add("${jetty.home}/start.d/ssl.ini"); + expected.add("${jetty.base}/start.d/myapp.ini"); + FSTest.toOsSeparators(expected); + + assertPathList(hb,"Paths found",expected,paths); + } + + @Test + public void testDefault() throws IOException + { + BaseHome bh = new BaseHome(); + Assert.assertThat("Home",bh.getHome(),notNullValue()); + Assert.assertThat("Base",bh.getBase(),notNullValue()); + } + + @Test + public void testGetPath_Both() throws IOException + { + File homeDir = MavenTestingUtils.getTestResourceDir("hb.1/home"); + File baseDir = MavenTestingUtils.getTestResourceDir("hb.1/base"); + + ConfigSources config = new ConfigSources(); + config.add(new JettyBaseConfigSource(baseDir.toPath())); + config.add(new JettyHomeConfigSource(homeDir.toPath())); + + BaseHome hb = new BaseHome(config); + Path startIni = hb.getPath("start.ini"); + + String ref = hb.toShortForm(startIni); + Assert.assertThat("Reference",ref,startsWith("${jetty.base}")); + + String contents = IO.readToString(startIni.toFile()); + Assert.assertThat("Contents",contents,containsString("Base Ini")); + } +} diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java index 2bdd2d7a730..b6a4fafb965 100644 --- a/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java +++ b/jetty-start/src/test/java/org/eclipse/jetty/start/ConfigurationAssert.java @@ -1,281 +1,281 @@ -// -// ======================================================================== -// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.start; - -import static org.hamcrest.Matchers.*; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.eclipse.jetty.start.Props.Prop; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.junit.Assert; - -public class ConfigurationAssert -{ - /** - * Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file. - * - * @param baseHome - * the BaseHome used. Access it via {@link Main#getBaseHome()} - * @param args - * the StartArgs that has been processed via {@link Main#processCommandLine(String[])} - * @param filename - * the filename of the assertion values - * @throws IOException - */ - public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException - { - Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toAbsolutePath(); - File file = MavenTestingUtils.getTestResourceFile(filename); - TextFile textFile = new TextFile(file.toPath()); - - // Validate XMLs (order is important) - List expectedXmls = new ArrayList<>(); - for (String line : textFile) - { - if (line.startsWith("XML|")) - { - expectedXmls.add(FS.separators(getValue(line))); - } - } - List actualXmls = new ArrayList<>(); - for (Path xml : args.getXmlFiles()) - { - actualXmls.add(shorten(baseHome,xml,testResourcesDir)); - } - assertOrdered("XML Resolution Order",expectedXmls,actualXmls); - - // Validate LIBs (order is not important) - List expectedLibs = new ArrayList<>(); - for (String line : textFile) - { - if (line.startsWith("LIB|")) - { - expectedLibs.add(FS.separators(getValue(line))); - } - } - List actualLibs = new ArrayList<>(); - for (File path : args.getClasspath()) - { - actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir)); - } - assertContainsUnordered("Libs",expectedLibs,actualLibs); - - // Validate PROPERTIES (order is not important) - Set expectedProperties = new HashSet<>(); - for (String line : textFile) - { - if (line.startsWith("PROP|")) - { - expectedProperties.add(getValue(line)); - } - } - List actualProperties = new ArrayList<>(); - for (Prop prop : args.getProperties()) - { - String name = prop.key; - if ("jetty.home".equals(name) || "jetty.base".equals(name) || - "user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP)) - { - // strip these out from assertion, to make assertions easier. - continue; - } - actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value)); - } - assertContainsUnordered("Properties",expectedProperties,actualProperties); - - // Validate Downloads - List expectedDownloads = new ArrayList<>(); - for (String line : textFile) - { - if (line.startsWith("DOWNLOAD|")) - { - expectedDownloads.add(getValue(line)); - } - } - List actualDownloads = new ArrayList<>(); - for (FileArg darg : args.getFiles()) - { - if (darg.uri != null) - { - actualDownloads.add(String.format("%s|%s",darg.uri,darg.location)); - } - } - assertContainsUnordered("Downloads",expectedDownloads,actualDownloads); - - // Validate Files/Dirs creation - List expectedFiles = new ArrayList<>(); - for(String line: textFile) - { - if(line.startsWith("FILE|")) - { - expectedFiles.add(getValue(line)); - } - } - List actualFiles = new ArrayList<>(); - for(FileArg farg: args.getFiles()) - { - if(farg.uri == null) - { - actualFiles.add(farg.location); - } - } - assertContainsUnordered("Files/Dirs",expectedFiles,actualFiles); - } - - private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir) - { - String value = baseHome.toShortForm(path); - if (value.startsWith("${")) - { - return value; - } - - if (path.startsWith(testResourcesDir)) - { - int len = testResourcesDir.toString().length(); - value = "${maven-test-resources}" + value.substring(len); - } - return value; - } - - public static void assertContainsUnordered(String msg, Collection expectedSet, Collection actualSet) - { - // same size? - boolean mismatch = expectedSet.size() != actualSet.size(); - - // test content - Set missing = new HashSet<>(); - for (String expected : expectedSet) - { - if (!actualSet.contains(expected)) - { - missing.add(expected); - } - } - - if (mismatch || missing.size() > 0) - { - // build up detailed error message - StringWriter message = new StringWriter(); - PrintWriter err = new PrintWriter(message); - - err.printf("%s: Assert Contains (Unordered)",msg); - if (mismatch) - { - err.print(" [size mismatch]"); - } - if (missing.size() >= 0) - { - err.printf(" [%d entries missing]",missing.size()); - } - err.println(); - err.printf("Actual Entries (size: %d)%n",actualSet.size()); - for (String actual : actualSet) - { - char indicator = expectedSet.contains(actual)?' ':'>'; - err.printf("%s| %s%n",indicator,actual); - } - err.printf("Expected Entries (size: %d)%n",expectedSet.size()); - for (String expected : expectedSet) - { - char indicator = actualSet.contains(expected)?' ':'>'; - err.printf("%s| %s%n",indicator,expected); - } - err.flush(); - Assert.fail(message.toString()); - } - } - - public static void assertOrdered(String msg, List expectedList, List actualList) - { - // same size? - boolean mismatch = expectedList.size() != actualList.size(); - - // test content - List badEntries = new ArrayList<>(); - int min = Math.min(expectedList.size(),actualList.size()); - int max = Math.max(expectedList.size(),actualList.size()); - for (int i = 0; i < min; i++) - { - if (!expectedList.get(i).equals(actualList.get(i))) - { - badEntries.add(i); - } - } - for (int i = min; i < max; i++) - { - badEntries.add(i); - } - - if (mismatch || badEntries.size() > 0) - { - // build up detailed error message - StringWriter message = new StringWriter(); - PrintWriter err = new PrintWriter(message); - - err.printf("%s: Assert Contains (Unordered)",msg); - if (mismatch) - { - err.print(" [size mismatch]"); - } - if (badEntries.size() >= 0) - { - err.printf(" [%d entries not matched]",badEntries.size()); - } - err.println(); - err.printf("Actual Entries (size: %d)%n",actualList.size()); - for (int i = 0; i < actualList.size(); i++) - { - String actual = actualList.get(i); - char indicator = badEntries.contains(i)?'>':' '; - err.printf("%s[%d] %s%n",indicator,i,actual); - } - - err.printf("Expected Entries (size: %d)%n",expectedList.size()); - for (int i = 0; i < expectedList.size(); i++) - { - String expected = expectedList.get(i); - char indicator = badEntries.contains(i)?'>':' '; - err.printf("%s[%d] %s%n",indicator,i,expected); - } - err.flush(); - Assert.fail(message.toString()); - } - } - - private static String getValue(String arg) - { - int idx = arg.indexOf('|'); - Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0)); - String value = arg.substring(idx + 1).trim(); - Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0)); - return value; - } -} +// +// ======================================================================== +// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.start; + +import static org.hamcrest.Matchers.*; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jetty.start.Props.Prop; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Assert; + +public class ConfigurationAssert +{ + /** + * Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file. + * + * @param baseHome + * the BaseHome used. Access it via {@link Main#getBaseHome()} + * @param args + * the StartArgs that has been processed via {@link Main#processCommandLine(String[])} + * @param filename + * the filename of the assertion values + * @throws IOException + */ + public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException + { + Path testResourcesDir = MavenTestingUtils.getTestResourcesDir().toPath().toAbsolutePath(); + File file = MavenTestingUtils.getTestResourceFile(filename); + TextFile textFile = new TextFile(file.toPath()); + + // Validate XMLs (order is important) + List expectedXmls = new ArrayList<>(); + for (String line : textFile) + { + if (line.startsWith("XML|")) + { + expectedXmls.add(FS.separators(getValue(line))); + } + } + List actualXmls = new ArrayList<>(); + for (Path xml : args.getXmlFiles()) + { + actualXmls.add(shorten(baseHome,xml,testResourcesDir)); + } + assertOrdered("XML Resolution Order",expectedXmls,actualXmls); + + // Validate LIBs (order is not important) + List expectedLibs = new ArrayList<>(); + for (String line : textFile) + { + if (line.startsWith("LIB|")) + { + expectedLibs.add(FS.separators(getValue(line))); + } + } + List actualLibs = new ArrayList<>(); + for (File path : args.getClasspath()) + { + actualLibs.add(shorten(baseHome,path.toPath(),testResourcesDir)); + } + assertContainsUnordered("Libs",expectedLibs,actualLibs); + + // Validate PROPERTIES (order is not important) + Set expectedProperties = new HashSet<>(); + for (String line : textFile) + { + if (line.startsWith("PROP|")) + { + expectedProperties.add(getValue(line)); + } + } + List actualProperties = new ArrayList<>(); + for (Prop prop : args.getProperties()) + { + String name = prop.key; + if ("jetty.home".equals(name) || "jetty.base".equals(name) || + "user.dir".equals(name) || prop.origin.equals(Props.ORIGIN_SYSPROP)) + { + // strip these out from assertion, to make assertions easier. + continue; + } + actualProperties.add(prop.key + "=" + args.getProperties().expand(prop.value)); + } + assertContainsUnordered("Properties",expectedProperties,actualProperties); + + // Validate Downloads + List expectedDownloads = new ArrayList<>(); + for (String line : textFile) + { + if (line.startsWith("DOWNLOAD|")) + { + expectedDownloads.add(getValue(line)); + } + } + List actualDownloads = new ArrayList<>(); + for (FileArg darg : args.getFiles()) + { + if (darg.uri != null) + { + actualDownloads.add(String.format("%s|%s",darg.uri,darg.location)); + } + } + assertContainsUnordered("Downloads",expectedDownloads,actualDownloads); + + // Validate Files/Dirs creation + List expectedFiles = new ArrayList<>(); + for(String line: textFile) + { + if(line.startsWith("FILE|")) + { + expectedFiles.add(getValue(line)); + } + } + List actualFiles = new ArrayList<>(); + for(FileArg farg: args.getFiles()) + { + if(farg.uri == null) + { + actualFiles.add(farg.location); + } + } + assertContainsUnordered("Files/Dirs",expectedFiles,actualFiles); + } + + private static String shorten(BaseHome baseHome, Path path, Path testResourcesDir) + { + String value = baseHome.toShortForm(path); + if (value.startsWith("${")) + { + return value; + } + + if (path.startsWith(testResourcesDir)) + { + int len = testResourcesDir.toString().length(); + value = "${maven-test-resources}" + value.substring(len); + } + return value; + } + + public static void assertContainsUnordered(String msg, Collection expectedSet, Collection actualSet) + { + // same size? + boolean mismatch = expectedSet.size() != actualSet.size(); + + // test content + Set missing = new HashSet<>(); + for (String expected : expectedSet) + { + if (!actualSet.contains(expected)) + { + missing.add(expected); + } + } + + if (mismatch || missing.size() > 0) + { + // build up detailed error message + StringWriter message = new StringWriter(); + PrintWriter err = new PrintWriter(message); + + err.printf("%s: Assert Contains (Unordered)",msg); + if (mismatch) + { + err.print(" [size mismatch]"); + } + if (missing.size() >= 0) + { + err.printf(" [%d entries missing]",missing.size()); + } + err.println(); + err.printf("Actual Entries (size: %d)%n",actualSet.size()); + for (String actual : actualSet) + { + char indicator = expectedSet.contains(actual)?' ':'>'; + err.printf("%s| %s%n",indicator,actual); + } + err.printf("Expected Entries (size: %d)%n",expectedSet.size()); + for (String expected : expectedSet) + { + char indicator = actualSet.contains(expected)?' ':'>'; + err.printf("%s| %s%n",indicator,expected); + } + err.flush(); + Assert.fail(message.toString()); + } + } + + public static void assertOrdered(String msg, List expectedList, List actualList) + { + // same size? + boolean mismatch = expectedList.size() != actualList.size(); + + // test content + List badEntries = new ArrayList<>(); + int min = Math.min(expectedList.size(),actualList.size()); + int max = Math.max(expectedList.size(),actualList.size()); + for (int i = 0; i < min; i++) + { + if (!expectedList.get(i).equals(actualList.get(i))) + { + badEntries.add(i); + } + } + for (int i = min; i < max; i++) + { + badEntries.add(i); + } + + if (mismatch || badEntries.size() > 0) + { + // build up detailed error message + StringWriter message = new StringWriter(); + PrintWriter err = new PrintWriter(message); + + err.printf("%s: Assert Contains (Unordered)",msg); + if (mismatch) + { + err.print(" [size mismatch]"); + } + if (badEntries.size() >= 0) + { + err.printf(" [%d entries not matched]",badEntries.size()); + } + err.println(); + err.printf("Actual Entries (size: %d)%n",actualList.size()); + for (int i = 0; i < actualList.size(); i++) + { + String actual = actualList.get(i); + char indicator = badEntries.contains(i)?'>':' '; + err.printf("%s[%d] %s%n",indicator,i,actual); + } + + err.printf("Expected Entries (size: %d)%n",expectedList.size()); + for (int i = 0; i < expectedList.size(); i++) + { + String expected = expectedList.get(i); + char indicator = badEntries.contains(i)?'>':' '; + err.printf("%s[%d] %s%n",indicator,i,expected); + } + err.flush(); + Assert.fail(message.toString()); + } + } + + private static String getValue(String arg) + { + int idx = arg.indexOf('|'); + Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0)); + String value = arg.substring(idx + 1).trim(); + Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0)); + return value; + } +} From ca77bd384a2970cabbbdab25cf6251c6fb76cd21 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 3 Apr 2019 16:28:26 -0500 Subject: [PATCH 43/74] Issue #3319 - Refactoring DefaultServlet Index/Listing + Now generates valid HTML5 + Now allows column sort Signed-off-by: Joakim Erdfelt --- .../jetty/embedded/FastFileServer.java | 4 +- .../jetty/server/handler/ResourceHandler.java | 3 +- .../eclipse/jetty/servlet/DefaultServlet.java | 3 +- .../jetty/servlet/DefaultServletTest.java | 21 +- .../eclipse/jetty/util/resource/Resource.java | 271 +++++++++++++++--- .../util/resource/ResourceCollators.java | 101 +++++++ jetty-util/src/main/resources/jetty-dir.css | 36 ++- 7 files changed, 373 insertions(+), 66 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollators.java diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/FastFileServer.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/FastFileServer.java index 3e1610b9c17..72c1c915961 100644 --- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/FastFileServer.java +++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/FastFileServer.java @@ -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; @@ -115,7 +114,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; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java index 367958c7da9..dcfc4bb107d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java @@ -23,7 +23,6 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; - import javax.servlet.AsyncContext; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -589,7 +588,7 @@ public class ResourceHandler extends HandlerWrapper { if (_directory) { - String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0); + String listing = resource.getListHTML(request.getRequestURI(),request.getPathInfo().lastIndexOf("/") > 0, request.getQueryString()); response.setContentType("text/html; charset=UTF-8"); response.getWriter().println(listing); } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java index fcd43db176b..a4071e09ed6 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/DefaultServlet.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.StringTokenizer; - import javax.servlet.AsyncContext; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; @@ -845,7 +844,7 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory else if (_contextHandler.getBaseResource() instanceof ResourceCollection) resource=_contextHandler.getBaseResource().addPath(pathInContext); - String dir = resource.getListHTML(base,pathInContext.length()>1); + String dir = resource.getListHTML(base,pathInContext.length()>1, request.getQueryString()); if (dir==null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java index fd3a81ea977..a2813ad4ef1 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/DefaultServletTest.java @@ -18,8 +18,6 @@ package org.eclipse.jetty.servlet; -import static org.junit.Assert.assertTrue; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -28,7 +26,6 @@ import java.nio.file.Files; import java.util.EnumSet; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -54,6 +51,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import static org.junit.Assert.assertTrue; + public class DefaultServletTest { @Rule @@ -133,9 +132,14 @@ public class DefaultServletTest /* create some content in the docroot */ File resBase = testdir.getFile("docroot"); FS.ensureDirExists(resBase); - assertTrue(new File(resBase, "one").mkdir()); + File one = new File(resBase, "one"); + assertTrue(one.mkdir()); assertTrue(new File(resBase, "two").mkdir()); assertTrue(new File(resBase, "three").mkdir()); + + File alert = new File(one, "onmouseclick='alert(oops)'"); + FS.touch(alert); + if (!OS.IS_WINDOWS) { assertTrue("Creating dir 'f??r' (Might not work in Windows)", new File(resBase, "f??r").mkdir()); @@ -163,6 +167,15 @@ public class DefaultServletTest } assertResponseNotContains("