Merge remote-tracking branch 'origin/jetty-9.4.x'
This commit is contained in:
commit
c3da8b27eb
|
@ -53,12 +53,15 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
||||||
|
|
||||||
public AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
|
public AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
|
||||||
{
|
{
|
||||||
this(httpConfiguration,"h2","h2-17","h2-16","h2-15","h2-14");
|
this(httpConfiguration,"h2");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration, String... protocols)
|
protected AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration, String... protocols)
|
||||||
{
|
{
|
||||||
super(protocols);
|
super(protocols);
|
||||||
|
for (String p:protocols)
|
||||||
|
if (!HTTP2ServerConnection.isSupportedProtocol(p))
|
||||||
|
throw new IllegalArgumentException("Unsupported HTTP2 Protocol variant: "+p);
|
||||||
this.httpConfiguration = Objects.requireNonNull(httpConfiguration);
|
this.httpConfiguration = Objects.requireNonNull(httpConfiguration);
|
||||||
addBean(httpConfiguration);
|
addBean(httpConfiguration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,15 @@ public class HTTP2CServerConnectionFactory extends HTTP2ServerConnectionFactory
|
||||||
|
|
||||||
public HTTP2CServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
|
public HTTP2CServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
|
||||||
{
|
{
|
||||||
super(httpConfiguration,"h2c","h2c-17","h2c-16","h2c-15","h2c-14");
|
this(httpConfiguration,"h2c");
|
||||||
|
}
|
||||||
|
|
||||||
|
public HTTP2CServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration, String... protocols)
|
||||||
|
{
|
||||||
|
super(httpConfiguration,protocols);
|
||||||
|
for (String p:protocols)
|
||||||
|
if (!HTTP2ServerConnection.isSupportedProtocol(p))
|
||||||
|
throw new IllegalArgumentException("Unsupported HTTP2 Protocol variant: "+p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -58,6 +58,31 @@ import org.eclipse.jetty.util.thread.ExecutionStrategy;
|
||||||
|
|
||||||
public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo
|
public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param protocol A HTTP2 protocol variant
|
||||||
|
* @return True if the protocol version is supported
|
||||||
|
*/
|
||||||
|
public static boolean isSupportedProtocol(String protocol)
|
||||||
|
{
|
||||||
|
switch(protocol)
|
||||||
|
{
|
||||||
|
case "h2":
|
||||||
|
case "h2-17":
|
||||||
|
case "h2-16":
|
||||||
|
case "h2-15":
|
||||||
|
case "h2-14":
|
||||||
|
case "h2c":
|
||||||
|
case "h2c-17":
|
||||||
|
case "h2c-16":
|
||||||
|
case "h2c-15":
|
||||||
|
case "h2c-14":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final Queue<HttpChannelOverHTTP2> channels = new ConcurrentArrayQueue<>();
|
private final Queue<HttpChannelOverHTTP2> channels = new ConcurrentArrayQueue<>();
|
||||||
private final ServerSessionListener listener;
|
private final ServerSessionListener listener;
|
||||||
private final HttpConfiguration httpConfig;
|
private final HttpConfiguration httpConfig;
|
||||||
|
|
|
@ -64,8 +64,7 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF
|
||||||
@Override
|
@Override
|
||||||
public boolean isAcceptable(String protocol, String tlsProtocol, String tlsCipher)
|
public boolean isAcceptable(String protocol, String tlsProtocol, String tlsCipher)
|
||||||
{
|
{
|
||||||
// TODO remove this draft 14 protection
|
// Implement 9.2.2 for draft 14
|
||||||
// Implement 9.2.2
|
|
||||||
boolean acceptable = "h2-14".equals(protocol) || !(HTTP2Cipher.isBlackListProtocol(tlsProtocol) && HTTP2Cipher.isBlackListCipher(tlsCipher));
|
boolean acceptable = "h2-14".equals(protocol) || !(HTTP2Cipher.isBlackListProtocol(tlsProtocol) && HTTP2Cipher.isBlackListCipher(tlsCipher));
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("proto={} tls={} cipher={} 9.2.2-acceptable={}",protocol,tlsProtocol,tlsCipher,acceptable);
|
LOG.debug("proto={} tls={} cipher={} 9.2.2-acceptable={}",protocol,tlsProtocol,tlsCipher,acceptable);
|
||||||
|
|
|
@ -86,6 +86,7 @@ public class JettyEffectiveWebXml extends JettyRunMojo
|
||||||
applyJettyXml ();
|
applyJettyXml ();
|
||||||
|
|
||||||
ServerSupport.configureHandlers(server, null);
|
ServerSupport.configureHandlers(server, null);
|
||||||
|
ServerSupport.configureDefaultConfigurationClasses(server);
|
||||||
|
|
||||||
//ensure config of the webapp based on settings in plugin
|
//ensure config of the webapp based on settings in plugin
|
||||||
configureWebApplication();
|
configureWebApplication();
|
||||||
|
|
|
@ -271,7 +271,7 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer
|
||||||
request.setAttribute("javax.servlet.request.key_size",keySize);
|
request.setAttribute("javax.servlet.request.key_size",keySize);
|
||||||
request.setAttribute("javax.servlet.request.ssl_session_id", idStr);
|
request.setAttribute("javax.servlet.request.ssl_session_id", idStr);
|
||||||
String sessionAttribute = getSslSessionAttribute();
|
String sessionAttribute = getSslSessionAttribute();
|
||||||
if (sessionAttribute != null && sessionAttribute.isEmpty())
|
if (sessionAttribute != null && !sessionAttribute.isEmpty())
|
||||||
request.setAttribute(sessionAttribute, sslSession);
|
request.setAttribute(sessionAttribute, sslSession);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||||
|
import org.eclipse.jetty.server.handler.HotSwapHandler;
|
||||||
import org.eclipse.jetty.toolchain.test.PropertyFlag;
|
import org.eclipse.jetty.toolchain.test.PropertyFlag;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
@ -71,7 +72,7 @@ public class HttpServerTestFixture
|
||||||
|
|
||||||
protected void startServer(ServerConnector connector) throws Exception
|
protected void startServer(ServerConnector connector) throws Exception
|
||||||
{
|
{
|
||||||
startServer(connector,new HandlerWrapper());
|
startServer(connector,new HotSwapHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void startServer(ServerConnector connector, Handler handler) throws Exception
|
protected void startServer(ServerConnector connector, Handler handler) throws Exception
|
||||||
|
@ -96,10 +97,9 @@ public class HttpServerTestFixture
|
||||||
|
|
||||||
protected void configureServer(Handler handler) throws Exception
|
protected void configureServer(Handler handler) throws Exception
|
||||||
{
|
{
|
||||||
HandlerWrapper current = (HandlerWrapper)_server.getHandler();
|
HotSwapHandler swapper = (HotSwapHandler)_server.getHandler();
|
||||||
current.stop();
|
swapper.setHandler(handler);
|
||||||
current.setHandler(handler);
|
handler.start();
|
||||||
current.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,20 +18,33 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.server.ssl;
|
package org.eclipse.jetty.server.ssl;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.isEmptyOrNullString;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
|
import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
|
||||||
|
@ -40,11 +53,16 @@ import org.eclipse.jetty.io.ssl.SslConnection;
|
||||||
import org.eclipse.jetty.server.AbstractConnectionFactory;
|
import org.eclipse.jetty.server.AbstractConnectionFactory;
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
import org.eclipse.jetty.server.HttpServerTestBase;
|
import org.eclipse.jetty.server.HttpServerTestBase;
|
||||||
|
import org.eclipse.jetty.server.Request;
|
||||||
|
import org.eclipse.jetty.server.SecureRequestCustomizer;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||||
import org.eclipse.jetty.toolchain.test.OS;
|
import org.eclipse.jetty.toolchain.test.OS;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
|
@ -121,8 +139,12 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
||||||
sslContextFactory.setTrustStorePath(keystorePath);
|
sslContextFactory.setTrustStorePath(keystorePath);
|
||||||
sslContextFactory.setTrustStorePassword("storepwd");
|
sslContextFactory.setTrustStorePassword("storepwd");
|
||||||
ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
|
ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
|
||||||
ServerConnector connector = new ServerConnector(_server,(Executor)null,(Scheduler)null,pool, 1, 1, AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory()));
|
|
||||||
|
|
||||||
|
HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory();
|
||||||
|
ServerConnector connector = new ServerConnector(_server,(Executor)null,(Scheduler)null,pool, 1, 1, AbstractConnectionFactory.getFactories(sslContextFactory,httpConnectionFactory));
|
||||||
|
SecureRequestCustomizer secureRequestCustomer = new SecureRequestCustomizer();
|
||||||
|
secureRequestCustomer.setSslSessionAttribute("SSL_SESSION");
|
||||||
|
httpConnectionFactory.getHttpConfiguration().addCustomizer(secureRequestCustomer);
|
||||||
|
|
||||||
startServer(connector);
|
startServer(connector);
|
||||||
|
|
||||||
|
@ -222,5 +244,67 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSecureRequestCustomizer() throws Exception
|
||||||
|
{
|
||||||
|
configureServer(new SecureRequestHandler());
|
||||||
|
|
||||||
|
try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort()))
|
||||||
|
{
|
||||||
|
OutputStream os = client.getOutputStream();
|
||||||
|
|
||||||
|
os.write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1));
|
||||||
|
os.flush();
|
||||||
|
|
||||||
|
// Read the response.
|
||||||
|
String response = readResponse(client);
|
||||||
|
|
||||||
|
System.err.println(response);
|
||||||
|
|
||||||
|
assertThat(response, containsString("HTTP/1.1 200 OK"));
|
||||||
|
assertThat(response, containsString("Hello world"));
|
||||||
|
assertThat(response, containsString("scheme='https'"));
|
||||||
|
assertThat(response, containsString("isSecure='true'"));
|
||||||
|
assertThat(response, containsString("X509Certificate='null'"));
|
||||||
|
|
||||||
|
Matcher matcher=Pattern.compile("cipher_suite='([^']*)'").matcher(response);
|
||||||
|
matcher.find();
|
||||||
|
assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null"))));
|
||||||
|
|
||||||
|
matcher=Pattern.compile("key_size='([^']*)'").matcher(response);
|
||||||
|
matcher.find();
|
||||||
|
assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null"))));
|
||||||
|
|
||||||
|
matcher=Pattern.compile("ssl_session_id='([^']*)'").matcher(response);
|
||||||
|
matcher.find();
|
||||||
|
assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null"))));
|
||||||
|
|
||||||
|
matcher=Pattern.compile("ssl_session='([^']*)'").matcher(response);
|
||||||
|
matcher.find();
|
||||||
|
assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SecureRequestHandler extends AbstractHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||||
|
{
|
||||||
|
baseRequest.setHandled(true);
|
||||||
|
response.setStatus(200);
|
||||||
|
response.getOutputStream().println("Hello world");
|
||||||
|
response.getOutputStream().println("scheme='"+request.getScheme()+"'");
|
||||||
|
response.getOutputStream().println("isSecure='"+request.isSecure()+"'");
|
||||||
|
response.getOutputStream().println("X509Certificate='"+request.getAttribute("javax.servlet.request.X509Certificate")+"'");
|
||||||
|
response.getOutputStream().println("cipher_suite='"+request.getAttribute("javax.servlet.request.cipher_suite")+"'");
|
||||||
|
response.getOutputStream().println("key_size='"+request.getAttribute("javax.servlet.request.key_size")+"'");
|
||||||
|
response.getOutputStream().println("ssl_session_id='"+request.getAttribute("javax.servlet.request.ssl_session_id")+"'");
|
||||||
|
SSLSession sslSession=(SSLSession)request.getAttribute("SSL_SESSION");
|
||||||
|
response.getOutputStream().println("ssl_session='"+sslSession+"'");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,3 @@ maven://org.slf4j/slf4j-jcl/${slf4j.version}|lib/slf4j/slf4j-jcl-${slf4j.version
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
lib/slf4j/slf4j-jcl-${slf4j.version}.jar
|
lib/slf4j/slf4j-jcl-${slf4j.version}.jar
|
||||||
|
|
||||||
[exec]
|
|
||||||
-Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
[description]
|
||||||
|
Provides a SLF4J implementation that logs to the Java Util Logging API.
|
||||||
|
To receive jetty logs enable the jetty-slf4j module.
|
||||||
|
|
||||||
|
[depend]
|
||||||
|
slf4j-api
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
slf4j-impl
|
||||||
|
|
||||||
|
[files]
|
||||||
|
maven://org.slf4j/slf4j-jdk14/${slf4j.version}|lib/slf4j/slf4j-jdk14-${slf4j.version}.jar
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
lib/slf4j/slf4j-jdk14-${slf4j.version}.jar
|
|
@ -13,6 +13,3 @@ maven://org.slf4j/slf4j-simple/${slf4j.version}|lib/slf4j/slf4j-simple-${slf4j.v
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
lib/slf4j/slf4j-simple-${slf4j.version}.jar
|
lib/slf4j/slf4j-simple-${slf4j.version}.jar
|
||||||
|
|
||||||
[exec]
|
|
||||||
-Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
|
|
||||||
|
|
Loading…
Reference in New Issue