diff --git a/Jenkinsfile b/Jenkinsfile index c36df9d72ee5..fa321ab3ad10 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -128,7 +128,7 @@ def slackNotif() { * * @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 + * @param consoleParsers array of console parsers to run */ def mavenBuild(jdk, cmdline, mvnName, consoleParsers) { script { @@ -138,7 +138,7 @@ def mavenBuild(jdk, cmdline, mvnName, consoleParsers) { "MAVEN_OPTS=-Xms2g -Xmx4g -Djava.awt.headless=true"]) { configFileProvider( [configFile(fileId: 'oss-settings.xml', variable: 'GLOBAL_MVN_SETTINGS')]) { - sh "mvn -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Premote-session-tests -Pci -V -B -e -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + + sh "mvn -s $GLOBAL_MVN_SETTINGS -Dmaven.repo.local=.repository -Premote-session-tests -Pci -fae -V -B -e -Djetty.testtracker.log=true $cmdline -Dunix.socket.tmp=" + env.JENKINS_HOME } } @@ -146,7 +146,6 @@ def mavenBuild(jdk, cmdline, mvnName, consoleParsers) { finally { junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml' - //archiveArtifacts artifacts: '**/jetty-webapp/target/**' if(consoleParsers!=null){ warnings consoleParsers: consoleParsers } diff --git a/aggregates/jetty-all/pom.xml b/aggregates/jetty-all/pom.xml index eaec520ea80d..c43ae8961a33 100644 --- a/aggregates/jetty-all/pom.xml +++ b/aggregates/jetty-all/pom.xml @@ -46,7 +46,7 @@ org.eclipse.jetty.toolchain jetty-build-support - 1.3 + 1.5 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 5d54401f2e84..764295ef859b 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 @@ -65,6 +65,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledOnJre; import org.junit.jupiter.api.condition.JRE; @@ -261,8 +262,8 @@ public void handshakeFailed(Event event, Throwable failure) // In JDK 11+, a mismatch on the client does not generate any bytes towards // the server, while in previous JDKs the client sends to the server the close_notify. - @EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10}) - @Test + // @EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10}) + @Disabled("No longer viable, TLS protocol behavior changed in 8u272") public void testMismatchBetweenTLSProtocolAndTLSCiphersOnClient() throws Exception { SslContextFactory serverTLSFactory = createServerSslContextFactory(); 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 38ad95fe444b..7599b45d3944 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 @@ -44,9 +44,8 @@ import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledOnJre; -import org.junit.jupiter.api.condition.JRE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -55,7 +54,7 @@ // This whole test is very specific to how TLS < 1.3 works. // Starting in Java 11, TLS/1.3 is now enabled by default. -@EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10}) +@Disabled("Since 8u272 this is no longer valid") public class SslBytesClientTest extends SslBytesTest { private ExecutorService threadPool; diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 4901475c562b..4dd62f2dcd0a 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -15,6 +15,32 @@ 28888 + + + + org.mortbay.jetty + h2spec-maven-plugin + + org.eclipse.jetty.http2.server.H2SpecServer + ${skipTests} + org.eclipse.jetty.h2spec + true + + 3.5 - Sends invalid connection preface + + + + + h2spec + test + + h2spec + + + + + + @@ -86,39 +112,5 @@ - - run-h2spec-in-docker - - - /var/run/docker.sock - - - - - - org.mortbay.jetty - h2spec-maven-plugin - - org.eclipse.jetty.http2.server.H2SpecServer - ${skipTests} - org.eclipse.jetty.h2spec - - 3.5 - Sends invalid connection preface - - - - - h2spec - test - - h2spec - - - - - - - - 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 deleted file mode 100644 index d507fe572002..000000000000 --- a/jetty-io/src/test/java/org/eclipse/jetty/io/SslEngineBehaviorTest.java +++ /dev/null @@ -1,142 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. -// ------------------------------------------------------------------------ -// 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.io; - -import java.io.File; -import java.nio.ByteBuffer; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLEngineResult; - -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; - - @BeforeAll - public static void startSsl() throws Exception - { - sslCtxFactory = new SslContextFactory.Server(); - File keystore = MavenTestingUtils.getTestResourceFile("keystore"); - sslCtxFactory.setKeyStorePath(keystore.getAbsolutePath()); - sslCtxFactory.setKeyStorePassword("storepwd"); - sslCtxFactory.setKeyManagerPassword("keypwd"); - sslCtxFactory.start(); - } - - @AfterAll - public static void stopSsl() throws Exception - { - sslCtxFactory.stop(); - } - - @Test - @EnabledOnJre(JRE.JAVA_8) - public void checkSslEngineBehaviour() throws Exception - { - SSLEngine server = sslCtxFactory.newSSLEngine(); - SSLEngine client = sslCtxFactory.newSSLEngine(); - - ByteBuffer netC2S = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); - ByteBuffer netS2C = ByteBuffer.allocate(server.getSession().getPacketBufferSize()); - ByteBuffer serverIn = ByteBuffer.allocate(server.getSession().getApplicationBufferSize()); - ByteBuffer serverOut = ByteBuffer.allocate(server.getSession().getApplicationBufferSize()); - ByteBuffer clientIn = ByteBuffer.allocate(client.getSession().getApplicationBufferSize()); - - SSLEngineResult result; - - // start the client - client.setUseClientMode(true); - client.beginHandshake(); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP, client.getHandshakeStatus()); - - // what if we try an unwrap? - netS2C.flip(); - result = client.unwrap(netS2C, clientIn); - // unwrap is a noop - assertEquals(SSLEngineResult.Status.OK, result.getStatus()); - assertEquals(0, result.bytesConsumed()); - assertEquals(0, result.bytesProduced()); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP, result.getHandshakeStatus()); - netS2C.clear(); - - // do the needed WRAP of empty buffer - result = client.wrap(BufferUtil.EMPTY_BUFFER, netC2S); - // unwrap is a noop - assertEquals(SSLEngineResult.Status.OK, result.getStatus()); - assertEquals(0, result.bytesConsumed()); - assertThat(result.bytesProduced(), greaterThan(0)); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus()); - netC2S.flip(); - assertEquals(netC2S.remaining(), result.bytesProduced()); - - // start the server - server.setUseClientMode(false); - server.beginHandshake(); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, server.getHandshakeStatus()); - - // what if we try a needless wrap? - serverOut.put(BufferUtil.toBuffer("Hello World")); - serverOut.flip(); - result = server.wrap(serverOut, netS2C); - // wrap is a noop - assertEquals(SSLEngineResult.Status.OK, result.getStatus()); - assertEquals(0, result.bytesConsumed()); - assertEquals(0, result.bytesProduced()); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus()); - - // Do the needed unwrap, to an empty buffer - result = server.unwrap(netC2S, BufferUtil.EMPTY_BUFFER); - assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus()); - assertEquals(0, result.bytesConsumed()); - assertEquals(0, result.bytesProduced()); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus()); - - // Do the needed unwrap, to a full buffer - serverIn.position(serverIn.limit()); - result = server.unwrap(netC2S, serverIn); - assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus()); - assertEquals(0, result.bytesConsumed()); - assertEquals(0, result.bytesProduced()); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result.getHandshakeStatus()); - - // Do the needed unwrap, to an empty buffer - serverIn.clear(); - result = server.unwrap(netC2S, serverIn); - assertEquals(SSLEngineResult.Status.OK, result.getStatus()); - assertThat(result.bytesConsumed(), greaterThan(0)); - assertEquals(0, result.bytesProduced()); - assertEquals(SSLEngineResult.HandshakeStatus.NEED_TASK, result.getHandshakeStatus()); - - server.getDelegatedTask().run(); - - assertEquals(SSLEngineResult.HandshakeStatus.NEED_WRAP, server.getHandshakeStatus()); - } -} diff --git a/jetty-osgi/test-jetty-osgi/pom.xml b/jetty-osgi/test-jetty-osgi/pom.xml index 362b280c4ff6..6552794ddecc 100644 --- a/jetty-osgi/test-jetty-osgi/pom.xml +++ b/jetty-osgi/test-jetty-osgi/pom.xml @@ -88,13 +88,13 @@ org.eclipse.platform org.eclipse.osgi - 3.13.100 + 3.16.0 test org.eclipse.platform org.eclipse.osgi.services - 3.7.100 + 3.9.0 test 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 f242949cf74f..04dcd3e21938 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 @@ -149,7 +149,6 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory, Welc private boolean _useFileMappedBuffer = false; private String _relativeResourceBase; private ServletHandler _servletHandler; - private ServletHolder _defaultHolder; public DefaultServlet(ResourceService resourceService) { @@ -303,11 +302,6 @@ public void init() _resourceService.setGzipEquivalentFileExtensions(gzipEquivalentFileExtensions); _servletHandler = _contextHandler.getChildHandlerByClass(ServletHandler.class); - for (ServletHolder h : _servletHandler.getServlets()) - { - if (h.getServletInstance() == this) - _defaultHolder = h; - } if (LOG.isDebugEnabled()) LOG.debug("resource base = " + _resourceBase); @@ -504,9 +498,9 @@ public String getWelcomeFile(String pathInContext) return null; String welcomeServlet = null; - for (int i = 0; i < _welcomes.length; i++) + for (String s : _welcomes) { - String welcomeInContext = URIUtil.addPaths(pathInContext, _welcomes[i]); + String welcomeInContext = URIUtil.addPaths(pathInContext, s); Resource welcome = getResource(welcomeInContext); if (welcome != null && welcome.exists()) return welcomeInContext; @@ -514,9 +508,7 @@ public String getWelcomeFile(String pathInContext) if ((_welcomeServlets || _welcomeExactServlets) && welcomeServlet == null) { MappedResource entry = _servletHandler.getMappedServlet(welcomeInContext); - @SuppressWarnings("ReferenceEquality") - boolean isDefaultHolder = (entry.getResource() != _defaultHolder); - if (entry != null && isDefaultHolder && + if (entry != null && entry.getResource().getServletInstance() != this && (_welcomeServlets || (_welcomeExactServlets && entry.getPathSpec().getDeclaration().equals(welcomeInContext)))) welcomeServlet = welcomeInContext; } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java index 6f4af7368b78..320d93eb8e6a 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/FilterHolder.java @@ -222,7 +222,8 @@ public void dump(Appendable out, String indent) throws IOException @Override public String toString() { - return String.format("%s@%x==%s,inst=%b,async=%b", getName(), hashCode(), getClassName(), _filter != null, isAsyncSupported()); + return String.format("%s==%s@%x{inst=%b,async=%b,src=%s}", + getName(), getClassName(), hashCode(), _filter != null, isAsyncSupported(), getSource()); } public FilterRegistration.Dynamic getRegistration() diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java index 09cb5ee81f30..1fe1ef1f7b48 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/Invoker.java @@ -231,6 +231,7 @@ protected void service(HttpServletRequest request, HttpServletResponse response) if (holder != null) { final Request baseRequest = Request.getBaseRequest(request); + holder.prepare(baseRequest, request, response); holder.handle(baseRequest, new InvokedRequest(request, included, servlet, servletPath, pathInfo), response); diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java index 42d4c0549a82..2b1cb62c7a0c 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java @@ -126,7 +126,7 @@ public void doStop() throws Exception @Override public String toString() { - return super.toString() + ": " + getClassName(); + return String.format("%s@%x{src=%s}", getClassName(), hashCode(), getSource()); } /** diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java index 4929c16f9300..f84d21c4a46e 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHolder.java @@ -34,6 +34,7 @@ import java.util.Set; import java.util.Stack; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; import javax.servlet.GenericServlet; import javax.servlet.MultipartConfigElement; import javax.servlet.Servlet; @@ -80,8 +81,6 @@ public class ServletHolder extends Holder implements UserIdentity.Scope private Map _roleMap; private String _forcedPath; private String _runAsRole; - private RunAsToken _runAsToken; - private IdentityService _identityService; private ServletRegistration.Dynamic _registration; private JspContainer _jspContainer; @@ -394,12 +393,6 @@ public void doStart() checkInitOnStartup(); _config = new Config(); - - synchronized (this) - { - if (getHeldClass() != null && javax.servlet.SingleThreadModel.class.isAssignableFrom(getHeldClass())) - _servlet = new SingleThreadedWrapper(); - } } @Override @@ -447,13 +440,22 @@ public void destroyInstance(Object o) Servlet servlet = (Servlet)o; - // need to use the unwrapped servlet because lifecycle callbacks such as + // call any predestroy callbacks + predestroyServlet(servlet); + + // Call the servlet destroy + servlet.destroy(); + } + + private void predestroyServlet(Servlet servlet) + { + // TODO We should only predestroy instnaces that we created + // TODO But this breaks tests in jetty-9, so review behaviour in jetty-10 + + // Need to use the unwrapped servlet because lifecycle callbacks such as // postconstruct and predestroy are based off the classname and the wrapper // classes are unknown outside the ServletHolder getServletHandler().destroyServlet(unwrap(servlet)); - - // destroy the wrapped servlet, in case there is special behaviour - servlet.destroy(); } /** @@ -465,16 +467,20 @@ public void destroyInstance(Object o) public Servlet getServlet() throws ServletException { - synchronized (this) + Servlet servlet = _servlet; + if (servlet == null) { - if (_servlet == null && isRunning()) + synchronized (this) { - if (getHeldClass() != null) - initServlet(); + if (_servlet == null && isRunning()) + { + if (getHeldClass() != null) + initServlet(); + } + servlet = _servlet; } } - - return _servlet; + return servlet; } /** @@ -528,7 +534,16 @@ private Servlet makeUnavailable(UnavailableException e) { synchronized (this) { - _servlet = new UnavailableServlet(e, _servlet); + if (_servlet instanceof UnavailableServlet) + { + Throwable cause = ((UnavailableServlet)_servlet).getUnavailableException(); + if (cause != e) + cause.addSuppressed(e); + } + else + { + _servlet = new UnavailableServlet(e, _servlet); + } return _servlet; } } @@ -554,36 +569,41 @@ private void makeUnavailable(final Throwable e) } } - private synchronized void initServlet() + private void initServlet() throws ServletException { + // must be called with lock held and _servlet==null + if (_servlet != null) + throw new IllegalStateException("Servlet already initialised: " + _servlet); + + Servlet servlet = null; try { - if (_servlet == null) - _servlet = getInstance(); - if (_servlet == null) - _servlet = newInstance(); + servlet = getInstance(); + if (servlet == null) + servlet = newInstance(); + if (servlet instanceof javax.servlet.SingleThreadModel) + { + predestroyServlet(servlet); + servlet = new SingleThreadedWrapper(); + } + if (_config == null) _config = new Config(); //check run-as rolename and convert to token from IdentityService - if (_runAsRole == null) + if (_runAsRole != null) { - _identityService = null; - _runAsToken = null; - } - else - { - _identityService = getServletHandler().getIdentityService(); - if (_identityService != null) + IdentityService identityService = getServletHandler().getIdentityService(); + if (identityService != null) { - _runAsToken = _identityService.newRunAsToken(_runAsRole); - _servlet = new RunAs(_servlet, _identityService, _runAsToken); + RunAsToken runAsToken = identityService.newRunAsToken(_runAsRole); + servlet = new RunAs(servlet, identityService, runAsToken); } } if (!isAsyncSupported()) - _servlet = new NotAsync(_servlet); + servlet = new NotAsync(servlet); // Handle configuring servlets that implement org.apache.jasper.servlet.JspServlet if (isJspServlet()) @@ -595,28 +615,30 @@ else if (_forcedPath != null) detectJspContainer(); initMultiPart(); - _servlet = wrap(_servlet, WrapFunction.class, WrapFunction::wrapServlet); + servlet = wrap(servlet, WrapFunction.class, WrapFunction::wrapServlet); if (LOG.isDebugEnabled()) LOG.debug("Servlet.init {} for {}", _servlet, getName()); - _servlet.init(_config); - } - catch (UnavailableException e) - { - makeUnavailable(e); - if (getServletHandler().isStartWithUnavailable()) - LOG.warn(e); - else - throw e; + try + { + servlet.init(_config); + _servlet = servlet; + } + catch (UnavailableException e) + { + _servlet = new UnavailableServlet(e, servlet); + } } catch (ServletException e) { makeUnavailable(e.getCause() == null ? e : e.getCause()); + predestroyServlet(servlet); throw e; } catch (Exception e) { makeUnavailable(e); + predestroyServlet(servlet); throw new ServletException(this.toString(), e); } } @@ -651,8 +673,8 @@ protected void initJspServlet() throws Exception } scratch = new File(getInitParameter("scratchdir")); - if (!scratch.exists()) - scratch.mkdir(); + if (!scratch.exists() && !scratch.mkdir()) + throw new IllegalStateException("Could not create JSP scratch directory"); } /** @@ -725,10 +747,16 @@ public void setRunAsRole(String role) protected void prepare(Request baseRequest, ServletRequest request, ServletResponse response) throws ServletException, UnavailableException { + // Ensure the servlet is initialized prior to any filters being invoked getServlet(); - MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig(); - if (mpce != null) - baseRequest.setAttribute(Request.MULTIPART_CONFIG_ELEMENT, mpce); + + // Check for multipart config + if (_registration != null) + { + MultipartConfigElement mpce = ((Registration)_registration).getMultipartConfig(); + if (mpce != null) + baseRequest.setAttribute(Request.MULTIPART_CONFIG_ELEMENT, mpce); + } } @Deprecated @@ -757,7 +785,7 @@ public void handle(Request baseRequest, { try { - Servlet servlet = getServlet(); + Servlet servlet = getServletInstance(); if (servlet == null) throw new UnavailableException("Servlet Not Initialized"); servlet.service(request, response); @@ -1197,72 +1225,69 @@ public void dump(Appendable out, String indent) throws IOException @Override public String toString() { - return String.format("%s@%x==%s,jsp=%s,order=%d,inst=%b,async=%b", getName(), hashCode(), getClassName(), _forcedPath, _initOrder, _servlet != null, isAsyncSupported()); + return String.format("%s==%s@%x{jsp=%s,order=%d,inst=%b,async=%b,src=%s}", + getName(), getClassName(), hashCode(), + _forcedPath, _initOrder, _servlet != null, isAsyncSupported(), getSource()); } - private class UnavailableServlet extends GenericServlet + private class UnavailableServlet extends Wrapper { final UnavailableException _unavailableException; - final Servlet _servlet; - final long _available; + final AtomicLong _unavailableStart; public UnavailableServlet(UnavailableException unavailableException, Servlet servlet) { - _unavailableException = unavailableException; - - if (unavailableException.isPermanent()) + super(servlet != null ? servlet : new GenericServlet() { - _servlet = null; - _available = -1; - if (servlet != null) + @Override + public void service(ServletRequest req, ServletResponse res) throws IOException { - try - { - destroyInstance(servlet); - } - catch (Throwable th) - { - if (th != unavailableException) - unavailableException.addSuppressed(th); - } + ((HttpServletResponse)res).sendError(HttpServletResponse.SC_NOT_FOUND); } - } + }); + _unavailableException = unavailableException; + + if (unavailableException.isPermanent()) + _unavailableStart = null; else { - _servlet = servlet; - _available = System.nanoTime() + TimeUnit.SECONDS.toNanos(unavailableException.getUnavailableSeconds()); + long start = System.nanoTime(); + while (start == 0) + start = System.nanoTime(); + _unavailableStart = new AtomicLong(start); } } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - if (_available == -1) + if (LOG.isDebugEnabled()) + LOG.debug("Unavailable {}", req, _unavailableException); + if (_unavailableStart == null) + { ((HttpServletResponse)res).sendError(HttpServletResponse.SC_NOT_FOUND); - else if (System.nanoTime() < _available) - ((HttpServletResponse)res).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + } else { - synchronized (ServletHolder.this) + long start = _unavailableStart.get(); + + if (start == 0 || System.nanoTime() - start < TimeUnit.SECONDS.toNanos(_unavailableException.getUnavailableSeconds())) { - ServletHolder.this._servlet = this._servlet; - _servlet.service(req, res); + ((HttpServletResponse)res).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); } - } - } - - @Override - public void destroy() - { - if (_servlet != null) - { - try + else if (_unavailableStart.compareAndSet(start, 0)) { - destroyInstance(_servlet); + synchronized (this) + { + _servlet = getWrapped(); + } + Request baseRequest = Request.getBaseRequest(req); + ServletHolder.this.prepare(baseRequest, req, res); + ServletHolder.this.handle(baseRequest, req, res); } - catch (Throwable th) + else { - LOG.warn(th); + ((HttpServletResponse)res).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); } } } @@ -1294,53 +1319,53 @@ public interface WrapFunction public static class Wrapper implements Servlet, Wrapped { - private final Servlet _servlet; + private final Servlet _wrappedServlet; public Wrapper(Servlet servlet) { - _servlet = Objects.requireNonNull(servlet, "Servlet cannot be null"); + _wrappedServlet = Objects.requireNonNull(servlet, "Servlet cannot be null"); } @Override public Servlet getWrapped() { - return _servlet; + return _wrappedServlet; } @Override public void init(ServletConfig config) throws ServletException { - _servlet.init(config); + _wrappedServlet.init(config); } @Override public ServletConfig getServletConfig() { - return _servlet.getServletConfig(); + return _wrappedServlet.getServletConfig(); } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - _servlet.service(req, res); + _wrappedServlet.service(req, res); } @Override public String getServletInfo() { - return _servlet.getServletInfo(); + return _wrappedServlet.getServletInfo(); } @Override public void destroy() { - _servlet.destroy(); + _wrappedServlet.destroy(); } @Override public String toString() { - return String.format("%s:%s", this.getClass().getSimpleName(), _servlet.toString()); + return String.format("%s:%s", this.getClass().getSimpleName(), _wrappedServlet.toString()); } } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java index 45668965ed7f..59064a280a57 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ErrorPageTest.java @@ -422,6 +422,7 @@ public void testPermanentlyUnavailable() throws Exception __destroyed = new AtomicBoolean(false); String response = _connector.getResponse("GET /unavailable/info HTTP/1.0\r\n\r\n"); assertThat(response, Matchers.containsString("HTTP/1.1 404 ")); + _server.stop(); assertTrue(__destroyed.get()); } } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletLifeCycleTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletLifeCycleTest.java index 0e49712f836b..65d92ee5d5a0 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletLifeCycleTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletLifeCycleTest.java @@ -59,6 +59,10 @@ public void testLifeCycle() throws Exception context.getObjectFactory().addDecorator(new TestDecorator()); + // TODO review this test in jetty-10. Instances that are created externally and passed in should not be + // TODO decorated by the object factory unless: a) there is an explicit call to ServletContext.createXxx; + // TODO ; and b) the Servlet dyanmic API is used to register them. + ServletHandler sh = context.getServletHandler(); sh.addListener(new ListenerHolder(TestListener.class)); //added directly to ServletHandler context.addEventListener(context.getServletContext().createListener(TestListener2.class));//create,decorate and add listener to context - no holder! diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java index 3a9b07e795a8..1fb5793ac6fd 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java @@ -20,6 +20,7 @@ import java.util.concurrent.CopyOnWriteArrayList; +import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.Uptime; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -280,13 +281,9 @@ public void lifeCycleStopping(LifeCycle event) @Override public String toString() { - Class clazz = getClass(); - String name = clazz.getSimpleName(); - if ((name == null || name.length() == 0) && clazz.getSuperclass() != null) - { - clazz = clazz.getSuperclass(); - name = clazz.getSimpleName(); - } + String name = getClass().getSimpleName(); + if (StringUtil.isBlank(name) && getClass().getSuperclass() != null) + name = getClass().getSuperclass().getSimpleName(); return String.format("%s@%x{%s}", name, hashCode(), getState()); } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java index e9931f548e43..e29e285c4b11 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java @@ -571,11 +571,7 @@ public String[] list() int size = entries.size(); return entries.toArray(new String[size]); } - catch (DirectoryIteratorException e) - { - LOG.debug(e); - } - catch (IOException e) + catch (DirectoryIteratorException | IOException e) { LOG.debug(e); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java index 594ba49c3b3c..3f080072465a 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java @@ -434,11 +434,12 @@ public long length() public String[] list() { assertResourcesSet(); - HashSet set = new HashSet<>(); for (Resource r : _resources) { - Collections.addAll(set, r.list()); + String[] list = r.list(); + if (list != null) + Collections.addAll(set, list); } String[] result = set.toArray(new String[0]); Arrays.sort(result); 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 8776e4182051..5ec5e82b7b2b 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 @@ -47,14 +47,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Consumer; -import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.net.ssl.CertPathTrustManagerParameters; import javax.net.ssl.HostnameVerifier; @@ -140,7 +138,7 @@ public class SslContextFactory extends AbstractLifeCycle implements Dumpable private final Set _excludeProtocols = new LinkedHashSet<>(); private final Set _includeProtocols = new LinkedHashSet<>(); private final Set _excludeCipherSuites = new LinkedHashSet<>(); - private final List _includeCipherSuites = new ArrayList<>(); + private final Set _includeCipherSuites = new LinkedHashSet<>(); private final Map _aliasX509 = new HashMap<>(); private final Map _certHosts = new HashMap<>(); private final Map _certWilds = new HashMap<>(); @@ -526,6 +524,8 @@ public String[] getExcludeProtocols() } /** + * You can either use the exact Protocol name or a a regular expression. + * * @param protocols The array of protocol names to exclude from * {@link SSLEngine#setEnabledProtocols(String[])} */ @@ -536,7 +536,9 @@ public void setExcludeProtocols(String... protocols) } /** - * @param protocol Protocol names to add to {@link SSLEngine#setEnabledProtocols(String[])} + * You can either use the exact Protocol name or a a regular expression. + * + * @param protocol Protocol name patterns to add to {@link SSLEngine#setEnabledProtocols(String[])} */ public void addExcludeProtocols(String... protocol) { @@ -544,7 +546,7 @@ public void addExcludeProtocols(String... protocol) } /** - * @return The array of protocol names to include in + * @return The array of protocol name patterns to include in * {@link SSLEngine#setEnabledProtocols(String[])} */ @ManagedAttribute("The included TLS protocols") @@ -554,7 +556,9 @@ public String[] getIncludeProtocols() } /** - * @param protocols The array of protocol names to include in + * You can either use the exact Protocol name or a a regular expression. + * + * @param protocols The array of protocol name patterns to include in * {@link SSLEngine#setEnabledProtocols(String[])} */ public void setIncludeProtocols(String... protocols) @@ -564,7 +568,7 @@ public void setIncludeProtocols(String... protocols) } /** - * @return The array of cipher suite names to exclude from + * @return The array of cipher suite name patterns to exclude from * {@link SSLEngine#setEnabledCipherSuites(String[])} */ @ManagedAttribute("The excluded cipher suites") @@ -574,7 +578,7 @@ public String[] getExcludeCipherSuites() } /** - * You can either use the exact cipher suite name or a a regular expression. + * You can either use the exact Cipher suite name or a a regular expression. * * @param cipherSuites The array of cipher suite names to exclude from * {@link SSLEngine#setEnabledCipherSuites(String[])} @@ -586,6 +590,8 @@ public void setExcludeCipherSuites(String... cipherSuites) } /** + * You can either use the exact Cipher suite name or a a regular expression. + * * @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])} */ public void addExcludeCipherSuites(String... cipher) @@ -594,7 +600,7 @@ public void addExcludeCipherSuites(String... cipher) } /** - * @return The array of cipher suite names to include in + * @return The array of Cipher suite names to include in * {@link SSLEngine#setEnabledCipherSuites(String[])} */ @ManagedAttribute("The included cipher suites") @@ -604,7 +610,7 @@ public String[] getIncludeCipherSuites() } /** - * You can either use the exact cipher suite name or a a regular expression. + * You can either use the exact Cipher suite name or a a regular expression. * * @param cipherSuites The array of cipher suite names to include in * {@link SSLEngine#setEnabledCipherSuites(String[])} @@ -1357,28 +1363,10 @@ protected PKIXBuilderParameters newPKIXBuilderParameters(KeyStore trustStore, Co */ public void selectProtocols(String[] enabledProtocols, String[] supportedProtocols) { - Set selectedProtocols = new LinkedHashSet<>(); - - // Set the starting protocols - either from the included or enabled list - if (!_includeProtocols.isEmpty()) - { - // Use only the supported included protocols - for (String protocol : _includeProtocols) - { - if (Arrays.asList(supportedProtocols).contains(protocol)) - selectedProtocols.add(protocol); - else - LOG.info("Protocol {} not supported in {}", protocol, Arrays.asList(supportedProtocols)); - } - } - else - selectedProtocols.addAll(Arrays.asList(enabledProtocols)); - - // Remove any excluded protocols - selectedProtocols.removeAll(_excludeProtocols); + List selectedProtocols = processIncludeExcludePatterns("Protocols", enabledProtocols, supportedProtocols, _includeProtocols, _excludeProtocols); if (selectedProtocols.isEmpty()) - LOG.warn("No selected protocols from {}", Arrays.asList(supportedProtocols)); + LOG.warn("No selected Protocols from {}", Arrays.asList(supportedProtocols)); _selectedProtocols = selectedProtocols.toArray(new String[0]); } @@ -1393,18 +1381,10 @@ public void selectProtocols(String[] enabledProtocols, String[] supportedProtoco */ protected void selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites) { - List selectedCiphers = new ArrayList<>(); - - // Set the starting ciphers - either from the included or enabled list - if (_includeCipherSuites.isEmpty()) - selectedCiphers.addAll(Arrays.asList(enabledCipherSuites)); - else - processIncludeCipherSuites(supportedCipherSuites, selectedCiphers); - - removeExcludedCipherSuites(selectedCiphers); + List selectedCiphers = processIncludeExcludePatterns("Cipher Suite", enabledCipherSuites, supportedCipherSuites, _includeCipherSuites, _excludeCipherSuites); if (selectedCiphers.isEmpty()) - LOG.warn("No supported ciphers from {}", Arrays.asList(supportedCipherSuites)); + LOG.warn("No supported Cipher Suite from {}", Arrays.asList(supportedCipherSuites)); Comparator comparator = getCipherComparator(); if (comparator != null) @@ -1417,39 +1397,58 @@ protected void selectCipherSuites(String[] enabledCipherSuites, String[] support _selectedCipherSuites = selectedCiphers.toArray(new String[0]); } - protected void processIncludeCipherSuites(String[] supportedCipherSuites, List selectedCiphers) + private List processIncludeExcludePatterns(String type, String[] enabled, String[] supported, Set included, Set excluded) { - for (String cipherSuite : _includeCipherSuites) + List selected = new ArrayList<>(); + // Set the starting list - either from the included or enabled list + if (included.isEmpty()) { - Pattern p = Pattern.compile(cipherSuite); - boolean added = false; - for (String supportedCipherSuite : supportedCipherSuites) + selected.addAll(Arrays.asList(enabled)); + } + else + { + // process include patterns + for (String includedItem : included) { - Matcher m = p.matcher(supportedCipherSuite); - if (m.matches()) + Pattern pattern = Pattern.compile(includedItem); + boolean added = false; + for (String supportedItem : supported) { - added = true; - selectedCiphers.add(supportedCipherSuite); + if (pattern.matcher(supportedItem).matches()) + { + added = true; + selected.add(supportedItem); + } } + if (!added) + LOG.info("No {} matching '{}' is supported", type, includedItem); } - if (!added) - LOG.info("No Cipher matching '{}' is supported", cipherSuite); } + + // process exclude patterns + for (String excludedItem : excluded) + { + Pattern pattern = Pattern.compile(excludedItem); + selected.removeIf(selectedItem -> pattern.matcher(selectedItem).matches()); + } + + return selected; } + /** + * @deprecated no replacement + */ + @Deprecated + protected void processIncludeCipherSuites(String[] supportedCipherSuites, List selectedCiphers) + { + } + + /** + * @deprecated no replacement + */ + @Deprecated protected void removeExcludedCipherSuites(List selectedCiphers) { - for (String excludeCipherSuite : _excludeCipherSuites) - { - Pattern excludeCipherPattern = Pattern.compile(excludeCipherSuite); - for (Iterator i = selectedCiphers.iterator(); i.hasNext(); ) - { - String selectedCipherSuite = i.next(); - Matcher m = excludeCipherPattern.matcher(selectedCipherSuite); - if (m.matches()) - i.remove(); - } - } } /** diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java index 51200037cce0..d3e212517c6f 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceCollectionTest.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.InputStreamReader; import java.nio.file.Path; +import java.util.Arrays; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; @@ -32,7 +33,9 @@ import org.junit.jupiter.api.extension.ExtendWith; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -174,6 +177,20 @@ private void assertThrowIllegalStateException(ResourceCollection coll) }); } + @Test + public void testList() throws Exception + { + ResourceCollection rc1 = new ResourceCollection( + Resource.newResource("src/test/resources/org/eclipse/jetty/util/resource/one/"), + Resource.newResource("src/test/resources/org/eclipse/jetty/util/resource/two/"), + Resource.newResource("src/test/resources/org/eclipse/jetty/util/resource/three/")); + + assertThat(Arrays.asList(rc1.list()), contains("1.txt", "2.txt", "3.txt", "dir/")); + assertThat(Arrays.asList(rc1.addPath("dir").list()), contains("1.txt", "2.txt", "3.txt")); + assertThat(rc1.addPath("unknown").list(), nullValue()); + // TODO for jetty-10 assertThat(rc1.addPath("unknown").list(), nullValue()); + } + @Test public void testMultipleSources1() throws Exception { 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 0ce32702e067..6171d2f19363 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 @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -46,7 +47,6 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.resource.Resource; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -55,6 +55,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasItemInArray; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.matchesRegex; import static org.hamcrest.Matchers.not; @@ -69,25 +70,10 @@ public class SslContextFactoryTest { - private SslContextFactory cf; - - @BeforeEach - public void setUp() throws Exception - { - 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(); - revocationChecker.setOptions(java.util.EnumSet.of( - java.security.cert.PKIXRevocationChecker.Option.valueOf("PREFER_CRLS"), - java.security.cert.PKIXRevocationChecker.Option.valueOf("SOFT_FAIL"), - java.security.cert.PKIXRevocationChecker.Option.valueOf("NO_FALLBACK"))); - cf.setPkixCertPathChecker(revocationChecker); - } - @Test public void testSLOTH() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.setKeyStorePassword("storepwd"); cf.setKeyManagerPassword("keypwd"); @@ -96,9 +82,13 @@ public void testSLOTH() throws Exception // cf.dump(System.out, ""); List dumps = cf.selectionDump(); - SslSelectionDump cipherDump = dumps.stream() + Optional cipherSuiteDumpOpt = dumps.stream() .filter((dump) -> dump.type.contains("Cipher Suite")) - .findFirst().get(); + .findFirst(); + + assertTrue(cipherSuiteDumpOpt.isPresent(), "Cipher Suite dump section should exist"); + + SslSelectionDump cipherDump = cipherSuiteDumpOpt.get(); for (String enabledCipher : cipherDump.enabled) { @@ -106,9 +96,42 @@ public void testSLOTH() throws Exception } } + @Test + public void testDumpExcludedProtocols() throws Exception + { + SslContextFactory.Server cf = new SslContextFactory.Server(); + cf.setExcludeProtocols("TLSv1\\.?[01]?"); + cf.start(); + + // Confirm behavior in engine + assertThat(cf.newSSLEngine().getEnabledProtocols(), not(hasItemInArray("TLSv1.1"))); + assertThat(cf.newSSLEngine().getEnabledProtocols(), not(hasItemInArray("TLSv1"))); + + // Confirm output in dump + List dumps = cf.selectionDump(); + + Optional protocolDumpOpt = dumps.stream() + .filter((dump) -> dump.type.contains("Protocol")) + .findFirst(); + + assertTrue(protocolDumpOpt.isPresent(), "Protocol dump section should exist"); + + SslSelectionDump protocolDump = protocolDumpOpt.get(); + + long countTls11Enabled = protocolDump.enabled.stream().filter((t) -> t.contains("TLSv1.1")).count(); + long countTls11Disabled = protocolDump.disabled.stream().filter((t) -> t.contains("TLSv1.1")).count(); + + assertThat("Enabled Protocols TLSv1.1 count", countTls11Enabled, is(0L)); + assertThat("Disabled Protocols TLSv1.1 count", countTls11Disabled, is(1L)); + + // Uncomment to show dump in console. + // cf.dump(System.out, ""); + } + @Test public void testDumpIncludeTlsRsa() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.setKeyStorePassword("storepwd"); cf.setKeyManagerPassword("keypwd"); cf.setIncludeCipherSuites("TLS_RSA_.*"); @@ -126,9 +149,15 @@ public void testDumpIncludeTlsRsa() throws Exception .collect(Collectors.toList()); List selectedSuites = Arrays.asList(cf.getSelectedCipherSuites()); - SslSelectionDump cipherDump = dumps.stream() + + Optional cipherSuiteDumpOpt = dumps.stream() .filter((dump) -> dump.type.contains("Cipher Suite")) - .findFirst().get(); + .findFirst(); + + assertTrue(cipherSuiteDumpOpt.isPresent(), "Cipher Suite dump section should exist"); + + SslSelectionDump cipherDump = cipherSuiteDumpOpt.get(); + assertThat("Dump Enabled List size is equal to selected list size", cipherDump.enabled.size(), is(selectedSuites.size())); for (String expectedCipherSuite : tlsRsaSuites) @@ -141,17 +170,19 @@ public void testDumpIncludeTlsRsa() throws Exception @Test public void testNoTsFileKs() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.setKeyStorePassword("storepwd"); cf.setKeyManagerPassword("keypwd"); cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testNoTsSetKs() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); KeyStore ks = KeyStore.getInstance("JKS"); try (InputStream keystoreInputStream = this.getClass().getResourceAsStream("keystore")) { @@ -162,26 +193,21 @@ public void testNoTsSetKs() throws Exception cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testNoTsNoKs() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.start(); - assertTrue(cf.getSslContext() != null); - } - - @Test - public void testTrustAll() throws Exception - { - cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testNoTsResourceKs() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); Resource keystoreResource = Resource.newSystemResource("keystore"); cf.setKeyStoreResource(keystoreResource); @@ -192,12 +218,13 @@ public void testNoTsResourceKs() throws Exception cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testResourceTsResourceKs() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); Resource keystoreResource = Resource.newSystemResource("keystore"); Resource truststoreResource = Resource.newSystemResource("keystore"); @@ -209,12 +236,13 @@ public void testResourceTsResourceKs() throws Exception cf.start(); - assertTrue(cf.getSslContext() != null); + assertNotNull(cf.getSslContext()); } @Test public void testResourceTsResourceKsWrongPW() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); Resource keystoreResource = Resource.newSystemResource("keystore"); Resource truststoreResource = Resource.newSystemResource("keystore"); @@ -227,7 +255,7 @@ public void testResourceTsResourceKsWrongPW() throws Exception try (StacklessLogging ignore = new StacklessLogging(AbstractLifeCycle.class)) { java.security.UnrecoverableKeyException x = assertThrows( - java.security.UnrecoverableKeyException.class, () -> cf.start()); + java.security.UnrecoverableKeyException.class, cf::start); assertThat(x.getMessage(), containsString("Cannot recover key")); } } @@ -235,6 +263,7 @@ public void testResourceTsResourceKsWrongPW() throws Exception @Test public void testResourceTsWrongPWResourceKs() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); Resource keystoreResource = Resource.newSystemResource("keystore"); Resource truststoreResource = Resource.newSystemResource("keystore"); @@ -246,14 +275,15 @@ public void testResourceTsWrongPWResourceKs() throws Exception try (StacklessLogging ignore = new StacklessLogging(AbstractLifeCycle.class)) { - IOException x = assertThrows(IOException.class, () -> cf.start()); + IOException x = assertThrows(IOException.class, cf::start); assertThat(x.getMessage(), containsString("Keystore was tampered with, or password was incorrect")); } } @Test - public void testNoKeyConfig() throws Exception + public void testNoKeyConfig() { + SslContextFactory.Server cf = new SslContextFactory.Server(); try (StacklessLogging ignore = new StacklessLogging(AbstractLifeCycle.class)) { IllegalStateException x = assertThrows(IllegalStateException.class, () -> @@ -268,6 +298,7 @@ public void testNoKeyConfig() throws Exception @Test public void testSetExcludeCipherSuitesRegex() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.setExcludeCipherSuites(".*RC4.*"); cf.start(); SSLEngine sslEngine = cf.newSSLEngine(); @@ -282,6 +313,7 @@ public void testSetExcludeCipherSuitesRegex() throws Exception @Test public void testSetIncludeCipherSuitesRegex() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.setIncludeCipherSuites(".*ECDHE.*", ".*WIBBLE.*"); cf.start(); @@ -297,6 +329,7 @@ public void testSetIncludeCipherSuitesRegex() throws Exception @Test public void testProtocolAndCipherSettingsAreNPESafe() { + SslContextFactory.Server cf = new SslContextFactory.Server(); assertNotNull(cf.getExcludeProtocols()); assertNotNull(cf.getIncludeProtocols()); assertNotNull(cf.getExcludeCipherSuites()); @@ -306,6 +339,7 @@ public void testProtocolAndCipherSettingsAreNPESafe() @Test public void testSNICertificates() throws Exception { + SslContextFactory.Server cf = new SslContextFactory.Server(); Resource keystoreResource = Resource.newSystemResource("snikeystore"); cf.setKeyStoreResource(keystoreResource); @@ -347,7 +381,7 @@ public void testSNICertificates() throws Exception @Test public void testNonDefaultKeyStoreTypeUsedForTrustStore() throws Exception { - cf = new SslContextFactory.Server(); + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.setKeyStoreResource(Resource.newSystemResource("keystore.p12")); cf.setKeyStoreType("pkcs12"); cf.setKeyStorePassword("storepwd"); @@ -365,7 +399,7 @@ public void testNonDefaultKeyStoreTypeUsedForTrustStore() throws Exception @Test public void testClientSslContextFactory() throws Exception { - cf = new SslContextFactory.Client(); + SslContextFactory.Client cf = new SslContextFactory.Client(); cf.start(); assertEquals("HTTPS", cf.getEndpointIdentificationAlgorithm()); @@ -374,7 +408,7 @@ public void testClientSslContextFactory() throws Exception @Test public void testServerSslContextFactory() throws Exception { - cf = new SslContextFactory.Server(); + SslContextFactory.Server cf = new SslContextFactory.Server(); cf.start(); assertNull(cf.getEndpointIdentificationAlgorithm()); diff --git a/pom.xml b/pom.xml index 461dc3e1424f..73d1ccd5b88b 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.8 https://eclipse.org/jetty UTF-8 - 1.4 + 1.5 8.36.2 1.7.30 2.11.2 @@ -34,7 +34,7 @@ 1.4.0 5.7.0 3.6.3 - 1.3.1 + 1.6.1 3.1.0 3.1.5.Final 3.4.1.Final @@ -726,12 +726,12 @@ org.asciidoctor asciidoctor-maven-plugin - 1.5.6 + 2.1.0 org.codehaus.mojo appassembler-maven-plugin - 2.0.0 + 2.1.0 org.codehaus.mojo @@ -936,7 +936,7 @@ org.mortbay.jetty h2spec-maven-plugin - 1.0.0 + 1.0.2 @@ -1154,7 +1154,7 @@ io.grpc grpc-core - 1.0.1 + 1.33.0 org.apache.ant diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index f6718611ce9b..eaf9a3960e3f 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -32,6 +32,21 @@ maven-resolver-provider ${maven.version} + + org.apache.maven.resolver + maven-resolver-util + ${maven.resolver.version} + + + org.apache.maven.resolver + maven-resolver-api + ${maven.resolver.version} + + + org.apache.maven.resolver + maven-resolver-spi + ${maven.resolver.version} + org.apache.maven.resolver maven-resolver-connector-basic