Merge remote-tracking branch 'origin/jetty-9.4.x'

This commit is contained in:
Jan Bartel 2016-07-06 13:43:52 +10:00
commit c3da8b27eb
11 changed files with 147 additions and 18 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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