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