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

This commit is contained in:
Jan Bartel 2017-09-21 13:59:17 +10:00
commit d2064599b8
67 changed files with 1867 additions and 480 deletions

View File

@ -124,26 +124,59 @@ jetty-9.4.6.v20170531 - 31 May 2017
+ 1569 Allow setting of maxBinaryMessageSize to 0 in WebSocketPolicy
+ 1579 NPE in Quoted Quality CSV
jetty-9.2.22.v20170606 - 06 June 2017
+ 920 no main manifest attribute, in jetty-runner-9.2.19.v20160908.jar
+ 1108 Please improve logging in SslContextFactory when there are no approved
cipher suites
jetty-9.3.21.v20170918 - 18 September 2017
+ 487 JDK 9 build compatibility
+ 1116 Support empty HTTP header values
+ 1357 RolloverFileOutputStream: No rollout performed at midnight
+ 1469 IllegalStateException in RolloverFileOutputStream
+ 1507 Negative delay Timer.schedule exception due to mismatched local and
_logTimeZone values
+ 1532 RolloverFileOutputStream can't handle multiple instances
+ 1523 Update ALPN support for Java 8u131
+ 1556 A timing channel in Password.java
+ 1590 RolloverFileOutputStream not functioning in Jetty 9.2.21+
+ 1469 RolloverFileOutputStream: IllegalStateException Task already scheduled
+ 1507 RolloverFileOutputStream: Negative delay Timer.schedule exception
+ 1513 RolloverFileOutputStream: can't handle multiple instances
+ 1515 Improved RollOverFileOutputStream removeOldFiles() behavior
+ 1556 Remove a timing channel in Password matching
+ 1590 Improve RolloverFileOutputStream functionality with multiple TimeZones
+ 1655 Improve extensibility of ServerConnector
+ 1661 AbstractProxyServlet onProxyResponseFailure Error
+ 1664 IPAccessHandler CIDR IP range check is incorrect
+ 1685 Update ALPN support for Java 8u141
+ 1687 HTTP2: Correcting missing callback notification when channel not found
+ 1702 Update ALPN support for Java 8u144
+ 1703 Improve HttpInput failure logging
+ 1719 HTTP/2: Improve handling of queued requests
+ 1741 Java 9 javadoc failure in build
+ 1749 Dump HttpDestination exchange queue
+ 1750 PoolingHttpDestination creates ConnectionPool twice
+ 1759 HTTP/2: producer can block in onReset
+ 1790 HTTP/2: 100% CPU usage seen during close/shutdown of endpoint
+ 475546 ClosedChannelException when connection to HTTPS over HTTP proxy
with CONNECT
jetty-9.3.20.v20170531 - 31 May 2017
jetty-9.4.6.v20170531 - 31 May 2017
+ 523 TLS close behaviour breaking session resumption
+ 1108 Please improve logging in SslContextFactory when there are no approved
cipher suites
+ 1505 Adding jetty.base.uri and jetty.home.uri
+ 1514 websocket dump badly formatted
+ 1516 Delay starting of WebSocketClient until an attempt to connect is made
+ 1520 PropertyUserStore should extract packed config file
+ 1526 MongoSessionDataStore old session scavenging is broken due to the
missing $ sign in "and" operation
+ 1527 Jetty BOM should not depend on jetty-parent
+ 1528 Internal HttpClient usages should have common configurable technique
+ 1536 Jetty BOM should include more artifacts
+ 1538 NPE in Response.putHeaders
+ 1539 JarFileResource mishandles paths with spaces
+ 1544 Disabling JSR-356 doesn't indicate context it was disabled for
+ 1546 Improve handling of quotes in cookies
+ 1553 X509.isCertSign() can throw ArrayIndexOutOfBoundsException on
non-standard implementations
+ 1556 A timing channel in Password.java
+ 1558 When creating WebAppContext without session-config and with NO_SESSIONS
throws NPE
+ 1567 XmlConfiguration will start the same object multiple times
+ 1568 ServletUpgradeRequest mangles query strings containing percent-escapes
by re-escaping them
+ 1569 Allow setting of maxBinaryMessageSize to 0 in WebSocketPolicy
+ 1579 NPE in Quoted Quality CSV
jetty-9.4.5.v20170502 - 02 May 2017
+ 304 Review dead code - StringUtil.sidBytesToString
@ -177,6 +210,27 @@ jetty-9.4.5.v20170502 - 02 May 2017
+ 1521 Prevent copy of jetty jars to lib/gcloud
+ 1523 Update ALPN support for Java 8u131
jetty-9.3.20.v20170531 - 31 May 2017
+ 523 TLS close behaviour breaking session resumption
+ 1108 Please improve logging in SslContextFactory when there are no approved
cipher suites
+ 1527 Jetty BOM should not depend on jetty-parent
+ 1556 A timing channel in Password.java
+ 1567 XmlConfiguration will start the same object multiple times
jetty-9.2.22.v20170606 - 06 June 2017
+ 920 no main manifest attribute, in jetty-runner-9.2.19.v20160908.jar
+ 1108 Please improve logging in SslContextFactory when there are no approved
cipher suites
+ 1357 RolloverFileOutputStream: No rollout performed at midnight
+ 1469 IllegalStateException in RolloverFileOutputStream
+ 1507 Negative delay Timer.schedule exception due to mismatched local and
_logTimeZone values
+ 1532 RolloverFileOutputStream can't handle multiple instances
+ 1523 Update ALPN support for Java 8u131
+ 1556 A timing channel in Password.java
+ 1590 RolloverFileOutputStream not functioning in Jetty 9.2.21+
jetty-9.3.19.v20170502 - 02 May 2017
+ 877 Programmatic servlet mappings cannot override mappings from
webdefault.xml using quickstart

View File

@ -75,6 +75,16 @@
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-conscrypt-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
@ -131,4 +141,20 @@
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>jdk9</id>
<activation>
<jdk>[1.9,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-java-server</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -19,8 +19,10 @@
package org.eclipse.jetty.embedded;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.util.Date;
import java.util.EnumSet;
@ -64,7 +66,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
public class Http2Server
{
public static void main(String... args) throws Exception
{
{
Server server = new Server();
MBeanContainer mbContainer = new MBeanContainer(
@ -72,7 +74,10 @@ public class Http2Server
server.addBean(mbContainer);
ServletContextHandler context = new ServletContextHandler(server, "/",ServletContextHandler.SESSIONS);
context.setResourceBase("src/main/resources/docroot");
String docroot = "src/main/resources/docroot";
if (!new File(docroot).exists())
docroot = "examples/embedded/src/main/resources/docroot";
context.setResourceBase(docroot);
context.addFilter(PushCacheFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
// context.addFilter(PushSessionCacheFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
context.addFilter(PushedTilesFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
@ -94,11 +99,14 @@ public class Http2Server
// SSL Context Factory for HTTPS and HTTP/2
String jetty_distro = System.getProperty("jetty.distro","../../jetty-distribution/target/distribution");
if (!new File(jetty_distro).exists())
jetty_distro = "jetty-distribution/target/distribution";
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(jetty_distro + "/demo-base/etc/keystore");
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
// sslContextFactory.setProvider("Conscrypt");
// HTTPS Configuration
HttpConfiguration https_config = new HttpConfiguration(http_config);

View File

@ -8,3 +8,4 @@
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG
#org.eclipse.jetty.server.LEVEL=DEBUG
#org.eclipse.jetty.servlets.LEVEL=DEBUG
#org.eclipse.jetty.alpn.LEVEL=DEBUG

View File

@ -50,12 +50,6 @@
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>

View File

@ -24,14 +24,13 @@ import java.util.concurrent.Executor;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.NegotiatingClientConnection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ALPNClientConnection extends NegotiatingClientConnection implements ALPN.ClientProvider
public class ALPNClientConnection extends NegotiatingClientConnection
{
private static final Logger LOG = Log.getLogger(ALPNClientConnection.class);
@ -41,41 +40,18 @@ public class ALPNClientConnection extends NegotiatingClientConnection implements
{
super(endPoint, executor, sslEngine, connectionFactory, context);
this.protocols = protocols;
ALPN.put(sslEngine, this);
}
@Override
public void unsupported()
{
ALPN.remove(getSSLEngine());
completed();
}
@Override
public List<String> protocols()
public List<String> getProtocols()
{
return protocols;
}
@Override
public void selected(String protocol)
{
if (protocols.contains(protocol))
{
ALPN.remove(getSSLEngine());
completed();
}
else
{
LOG.info("Could not negotiate protocol: server [{}] - client {}", protocol, protocols);
if (protocol==null || !protocols.contains(protocol))
close();
}
}
@Override
public void close()
{
ALPN.remove(getSSLEngine());
super.close();
else
super.completed();
}
}

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.alpn.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -31,17 +32,19 @@ import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.NegotiatingClientConnectionFactory;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.ALPNProcessor.Client;
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ALPNClientConnectionFactory extends NegotiatingClientConnectionFactory implements SslHandshakeListener
{
private final SslHandshakeListener alpnListener = new ALPNListener();
private static final Logger LOG = Log.getLogger(ALPNClientConnectionFactory.class);
private final List<Client> processors = new ArrayList<>();
private final Executor executor;
private final List<String> protocols;
private final ALPNProcessor.Client alpnProcessor;
public ALPNClientConnectionFactory(Executor executor, ClientConnectionFactory connectionFactory, List<String> protocols)
{
@ -50,39 +53,64 @@ public class ALPNClientConnectionFactory extends NegotiatingClientConnectionFact
throw new IllegalArgumentException("ALPN protocol list cannot be empty");
this.executor = executor;
this.protocols = protocols;
Iterator<ALPNProcessor.Client> processors = ServiceLoader.load(ALPNProcessor.Client.class).iterator();
alpnProcessor = processors.hasNext() ? processors.next() : ALPNProcessor.Client.NOOP;
}
public ALPNProcessor.Client getALPNProcessor()
{
return alpnProcessor;
IllegalStateException failure = new IllegalStateException("No Client ALPNProcessors!");
// Use a for loop on iterator so load exceptions can be caught and ignored
for (Iterator<Client> i = ServiceLoader.load(Client.class).iterator(); i.hasNext();)
{
Client processor;
try
{
processor = i.next();
}
catch(Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug(x);
failure.addSuppressed(x);
continue;
}
try
{
processor.init();
processors.add(processor);
}
catch (Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug("Could not initialize " + processor, x);
failure.addSuppressed(x);
}
}
if (LOG.isDebugEnabled())
{
LOG.debug("protocols: {}", protocols);
LOG.debug("processors: {}", processors);
}
if (processors.isEmpty())
throw failure;
}
@Override
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
{
SSLEngine sslEngine = (SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY);
getALPNProcessor().configure(sslEngine, protocols);
ContainerLifeCycle connector = (ContainerLifeCycle)context.get(ClientConnectionFactory.CONNECTOR_CONTEXT_KEY);
// Method addBean() has set semantic, so the listener is added only once.
connector.addBean(alpnListener);
ALPNClientConnection connection = new ALPNClientConnection(endPoint, executor, getClientConnectionFactory(),
sslEngine, context, protocols);
return customize(connection, context);
}
private class ALPNListener implements SslHandshakeListener
{
@Override
public void handshakeSucceeded(Event event)
{
getALPNProcessor().process(event.getSSLEngine());
}
@Override
public void handshakeFailed(Event event, Throwable failure)
SSLEngine engine = (SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY);
for (Client processor : processors)
{
if (processor.appliesTo(engine))
{
if (LOG.isDebugEnabled())
LOG.debug("{} for {} on {}", processor, engine, endPoint);
ALPNClientConnection connection = new ALPNClientConnection(endPoint, executor, getClientConnectionFactory(),
engine, context, protocols);
processor.configure(engine, connection);
return customize(connection, context);
}
}
throw new IllegalStateException("No ALPNProcessor for " + engine);
}
}

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.8-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-conscrypt-client</artifactId>
<name>Jetty :: ALPN :: Conscrypt Client Implementation</name>
<properties>
<bundle-symbolic-name>${project.groupId}.alpn.java.client</bundle-symbolic-name>
<conscrypt.version>1.0.0.RC10</conscrypt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.conscrypt</groupId>
<artifactId>conscrypt-openjdk-uber</artifactId>
<version>${conscrypt.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,107 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.conscrypt.client;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import javax.net.ssl.SSLEngine;
import org.conscrypt.OpenSSLProvider;
import org.eclipse.jetty.alpn.client.ALPNClientConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ConscryptClientALPNProcessor implements ALPNProcessor.Client
{
private static final Logger LOG = Log.getLogger(ConscryptClientALPNProcessor.class);
@Override
public void init()
{
if (Security.getProvider("Conscrypt")==null)
{
Security.addProvider(new OpenSSLProvider());
if (LOG.isDebugEnabled())
LOG.debug("Added Conscrypt provider");
}
}
@Override
public boolean appliesTo(SSLEngine sslEngine)
{
return sslEngine.getClass().getName().startsWith("org.conscrypt.");
}
@Override
public void configure(SSLEngine sslEngine, Connection connection)
{
try
{
Method setAlpnProtocols = sslEngine.getClass().getDeclaredMethod("setAlpnProtocols", String[].class);
setAlpnProtocols.setAccessible(true);
ALPNClientConnection alpn = (ALPNClientConnection)connection;
String[] protocols = alpn.getProtocols().toArray(new String[0]);
setAlpnProtocols.invoke(sslEngine, (Object)protocols);
((SslConnection.DecryptedEndPoint)connection.getEndPoint()).getSslConnection()
.addHandshakeListener(new ALPNListener(alpn));
}
catch (RuntimeException x)
{
throw x;
}
catch (Exception x)
{
throw new RuntimeException(x);
}
}
private final class ALPNListener implements SslHandshakeListener
{
private final ALPNClientConnection alpnConnection;
private ALPNListener(ALPNClientConnection connection)
{
alpnConnection = connection;
}
@Override
public void handshakeSucceeded(Event event)
{
try
{
SSLEngine sslEngine = alpnConnection.getSSLEngine();
Method method = sslEngine.getClass().getDeclaredMethod("getAlpnSelectedProtocol");
method.setAccessible(true);
String protocol = new String((byte[])method.invoke(sslEngine), StandardCharsets.US_ASCII);
alpnConnection.selected(protocol);
}
catch (Throwable e)
{
alpnConnection.selected(null);
LOG.warn(e);
}
}
}
}

View File

@ -0,0 +1 @@
org.eclipse.jetty.alpn.conscrypt.client.ConscryptClientALPNProcessor

View File

@ -0,0 +1,89 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.java.client;
import java.net.InetSocketAddress;
import java.security.Security;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.conscrypt.OpenSSLProvider;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class ConscryptHTTP2Client
{
public static void main(String[] args) throws Exception
{
Security.addProvider(new OpenSSLProvider());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setProvider("Conscrypt");
HTTP2Client client = new HTTP2Client();
client.addBean(sslContextFactory);
client.start();
String host = "webtide.com";
int port = 443;
FuturePromise<Session> sessionPromise = new FuturePromise<>();
client.connect(sslContextFactory, new InetSocketAddress(host, port), new Session.Listener.Adapter(), sessionPromise);
Session session = sessionPromise.get(5, TimeUnit.SECONDS);
HttpFields requestFields = new HttpFields();
requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION);
MetaData.Request metaData = new MetaData.Request("GET", new HttpURI("https://" + host + ":" + port + "/"), HttpVersion.HTTP_2, requestFields);
HeadersFrame headersFrame = new HeadersFrame(metaData, null, true);
CountDownLatch latch = new CountDownLatch(1);
session.newStream(headersFrame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
{
@Override
public void onHeaders(Stream stream, HeadersFrame frame)
{
System.err.println(frame);
if (frame.isEndStream())
latch.countDown();
}
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
System.err.println(frame);
callback.succeeded();
if (frame.isEndStream())
latch.countDown();
}
});
latch.await(5, TimeUnit.SECONDS);
client.stop();
}
}

View File

@ -0,0 +1,2 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.8-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-conscrypt-server</artifactId>
<name>Jetty :: ALPN :: Conscrypt Server Implementation</name>
<properties>
<bundle-symbolic-name>${project.groupId}.alpn.conscrypt.server</bundle-symbolic-name>
<conscrypt.version>1.0.0.RC10</conscrypt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.conscrypt</groupId>
<artifactId>conscrypt-openjdk-uber</artifactId>
<version>${conscrypt.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,115 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.conscrypt.server;
import java.lang.reflect.Method;
import java.security.Security;
import java.util.List;
import java.util.function.BiFunction;
import javax.net.ssl.SSLEngine;
import org.conscrypt.OpenSSLProvider;
import org.eclipse.jetty.alpn.server.ALPNServerConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ConscryptServerALPNProcessor implements ALPNProcessor.Server
{
private static final Logger LOG = Log.getLogger(ConscryptServerALPNProcessor.class);
@Override
public void init()
{
if (Security.getProvider("Conscrypt")==null)
{
Security.addProvider(new OpenSSLProvider());
if (LOG.isDebugEnabled())
LOG.debug("Added Conscrypt provider");
}
}
@Override
public boolean appliesTo(SSLEngine sslEngine)
{
return sslEngine.getClass().getName().startsWith("org.conscrypt.");
}
@Override
public void configure(SSLEngine sslEngine,Connection connection)
{
try
{
Method method = sslEngine.getClass().getMethod("setHandshakeApplicationProtocolSelector", BiFunction.class);
method.setAccessible(true);
method.invoke(sslEngine,new ALPNCallback((ALPNServerConnection)connection));
}
catch (RuntimeException x)
{
throw x;
}
catch (Exception x)
{
throw new RuntimeException(x);
}
}
private final class ALPNCallback implements BiFunction<SSLEngine,List<String>,String>, SslHandshakeListener
{
private final ALPNServerConnection alpnConnection;
private ALPNCallback(ALPNServerConnection connection)
{
alpnConnection = connection;
((DecryptedEndPoint)alpnConnection.getEndPoint()).getSslConnection().addHandshakeListener(this);
}
@Override
public String apply(SSLEngine engine, List<String> protocols)
{
if (LOG.isDebugEnabled())
LOG.debug("apply {} {}", alpnConnection, protocols);
alpnConnection.select(protocols);
return alpnConnection.getProtocol();
}
@Override
public void handshakeSucceeded(Event event)
{
if (LOG.isDebugEnabled())
LOG.debug("handshakeSucceeded {} {}", alpnConnection, event);
if (alpnConnection.getProtocol()==null)
{
LOG.warn("No ALPN callback! {} {}",alpnConnection, event);
alpnConnection.unsupported();
}
}
@Override
public void handshakeFailed(Event event, Throwable failure)
{
if (LOG.isDebugEnabled())
LOG.debug("handshakeFailed {} {} {}", alpnConnection, event, failure);
}
}
}

View File

@ -0,0 +1 @@
org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor

View File

@ -0,0 +1,72 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.conscrypt.server;
import java.security.Security;
import org.conscrypt.OpenSSLProvider;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.HTTP2Cipher;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
/**
* Test server that verifies that the Conscrypt ALPN mechanism works.
*/
public class ConscryptHTTP2Server
{
public static void main(String[] args) throws Exception
{
Security.addProvider(new OpenSSLProvider());
Server server = new Server();
HttpConfiguration httpsConfig = new HttpConfiguration();
httpsConfig.setSecureScheme("https");
httpsConfig.setSecurePort(8443);
httpsConfig.setSendXPoweredBy(true);
httpsConfig.setSendServerVersion(true);
httpsConfig.addCustomizer(new SecureRequestCustomizer());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setProvider("Conscrypt");
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
HttpConnectionFactory http = new HttpConnectionFactory(httpsConfig);
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig);
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
alpn.setDefaultProtocol(http.getProtocol());
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
ServerConnector http2Connector = new ServerConnector(server, ssl, alpn, h2, http);
http2Connector.setPort(8443);
server.addConnector(http2Connector);
server.start();
}
}

View File

@ -0,0 +1,3 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.alpn.LEVEL=DEBUG

View File

@ -33,22 +33,15 @@
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<artifactId>jetty-alpn-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -18,38 +18,66 @@
package org.eclipse.jetty.alpn.java.client;
import java.io.UncheckedIOException;
import java.util.List;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLParameters;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.client.ALPNClientConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslConnection.DecryptedEndPoint;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class JDK9ClientALPNProcessor implements ALPNProcessor.Client
{
private static final Logger LOG = Log.getLogger(JDK9ClientALPNProcessor.class);
@Override
public void configure(SSLEngine sslEngine, List<String> protocols)
public void init()
{
SSLParameters sslParameters = sslEngine.getSSLParameters();
sslParameters.setApplicationProtocols(protocols.toArray(new String[0]));
sslEngine.setSSLParameters(sslParameters);
if (JavaVersion.VERSION.getPlatform()<9)
throw new IllegalStateException(this + " not applicable for java "+JavaVersion.VERSION);
}
@Override
public void process(SSLEngine sslEngine)
public boolean appliesTo(SSLEngine sslEngine)
{
try
Module module = sslEngine.getClass().getModule();
return module!=null && "java.base".equals(module.getName());
}
@Override
public void configure(SSLEngine sslEngine, Connection connection)
{
ALPNClientConnection alpn = (ALPNClientConnection)connection;
SSLParameters sslParameters = sslEngine.getSSLParameters();
List<String> protocols = alpn.getProtocols();
sslParameters.setApplicationProtocols(protocols.toArray(new String[protocols.size()]));
sslEngine.setSSLParameters(sslParameters);
((DecryptedEndPoint)connection.getEndPoint()).getSslConnection()
.addHandshakeListener(new ALPNListener(alpn));
}
private final class ALPNListener implements SslHandshakeListener
{
private final ALPNClientConnection alpnConnection;
private ALPNListener(ALPNClientConnection connection)
{
ALPN.ClientProvider provider = (ALPN.ClientProvider)ALPN.get(sslEngine);
if (provider != null)
provider.selected(sslEngine.getApplicationProtocol());
alpnConnection = connection;
}
catch (SSLException x)
@Override
public void handshakeSucceeded(Event event)
{
throw new UncheckedIOException(x);
String protocol = alpnConnection.getSSLEngine().getApplicationProtocol();
if (LOG.isDebugEnabled())
LOG.debug("selected protocol {}", protocol);
alpnConnection.selected(protocol);
}
}
}

View File

@ -42,16 +42,16 @@ public class JDK9HTTP2Client
public static void main(String[] args) throws Exception
{
HTTP2Client client = new HTTP2Client();
SslContextFactory sslContextFactory = new SslContextFactory(true);
SslContextFactory sslContextFactory = new SslContextFactory();
client.addBean(sslContextFactory);
client.start();
String host = "localhost";
int port = 8443;
String host = "webtide.com";
int port = 443;
FuturePromise<Session> sessionPromise = new FuturePromise<>();
client.connect(sslContextFactory, new InetSocketAddress(host, port), new Session.Listener.Adapter(), sessionPromise);
Session session = sessionPromise.get(555, TimeUnit.SECONDS);
Session session = sessionPromise.get(5, TimeUnit.SECONDS);
HttpFields requestFields = new HttpFields();
requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION);

View File

@ -40,12 +40,10 @@
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
@ -53,12 +51,6 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View File

@ -19,13 +19,16 @@
package org.eclipse.jetty.alpn.java.server;
import java.util.List;
import java.util.function.BiFunction;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.server.ALPNServerConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -34,40 +37,61 @@ public class JDK9ServerALPNProcessor implements ALPNProcessor.Server, SslHandsha
private static final Logger LOG = Log.getLogger(JDK9ServerALPNProcessor.class);
@Override
public void configure(SSLEngine sslEngine)
public void init()
{
sslEngine.setHandshakeApplicationProtocolSelector(this::process);
}
private String process(SSLEngine sslEngine, List<String> protocols)
{
try
{
if (LOG.isDebugEnabled())
LOG.debug("ALPN selecting among client{}", protocols);
ALPN.ServerProvider provider = (ALPN.ServerProvider)ALPN.remove(sslEngine);
return provider == null ? "" : provider.select(protocols);
}
catch (SSLException x)
{
return null;
}
if (JavaVersion.VERSION.getPlatform()<9)
throw new IllegalStateException(this + " not applicable for java "+JavaVersion.VERSION);
}
@Override
public void handshakeSucceeded(Event event)
public boolean appliesTo(SSLEngine sslEngine)
{
ALPN.ServerProvider provider = (ALPN.ServerProvider)ALPN.remove(event.getSSLEngine());
if (provider != null)
{
if (LOG.isDebugEnabled())
LOG.debug("ALPN unsupported by client");
provider.unsupported();
}
Module module = sslEngine.getClass().getModule();
return module!=null && "java.base".equals(module.getName());
}
@Override
public void handshakeFailed(Event event, Throwable failure)
public void configure(SSLEngine sslEngine, Connection connection)
{
sslEngine.setHandshakeApplicationProtocolSelector(new ALPNCallback((ALPNServerConnection)connection));
}
private final class ALPNCallback implements BiFunction<SSLEngine,List<String>,String>, SslHandshakeListener
{
private final ALPNServerConnection alpnConnection;
private ALPNCallback(ALPNServerConnection connection)
{
alpnConnection = connection;
((SslConnection.DecryptedEndPoint)alpnConnection.getEndPoint()).getSslConnection().addHandshakeListener(this);
}
@Override
public String apply(SSLEngine engine, List<String> protocols)
{
if (LOG.isDebugEnabled())
LOG.debug("apply {} {}", alpnConnection, protocols);
alpnConnection.select(protocols);
return alpnConnection.getProtocol();
}
@Override
public void handshakeSucceeded(Event event)
{
if (LOG.isDebugEnabled())
LOG.debug("handshakeSucceeded {} {}", alpnConnection, event);
if (alpnConnection.getProtocol()==null)
{
LOG.warn("No ALPN callback! {} {}",alpnConnection, event);
alpnConnection.unsupported();
}
}
@Override
public void handshakeFailed(Event event, Throwable failure)
{
if (LOG.isDebugEnabled())
LOG.debug("handshakeFailed {} {} {}", alpnConnection, event, failure);
}
}
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.8-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-openjdk8-client</artifactId>
<name>Jetty :: ALPN :: OpenJDK8 Client Implementation</name>
<properties>
<bundle-symbolic-name>${project.groupId}.alpn.java.client</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,104 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.java.client;
import java.util.List;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.client.ALPNClientConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class OpenJDK8ClientALPNProcessor implements ALPNProcessor.Client
{
private static final Logger LOG = Log.getLogger(OpenJDK8ClientALPNProcessor.class);
@Override
public void init()
{
if (JavaVersion.VERSION.getPlatform()!=8)
throw new IllegalStateException(this + " not applicable for java "+JavaVersion.VERSION);
if (ALPN.class.getClassLoader()!=null)
throw new IllegalStateException(this + " must be on JVM boot classpath");
}
@Override
public boolean appliesTo(SSLEngine sslEngine)
{
return sslEngine.getClass().getName().startsWith("sun.security.ssl.");
}
@Override
public void configure(SSLEngine sslEngine, Connection connection)
{
connection.addListener(new ALPNListener((ALPNClientConnection)connection));
}
private final class ALPNListener implements ALPN.ClientProvider, Connection.Listener
{
private final ALPNClientConnection alpnConnection;
private ALPNListener(ALPNClientConnection connection)
{
alpnConnection = connection;
}
@Override
public void onOpened(Connection connection)
{
if (LOG.isDebugEnabled())
LOG.debug("onOpened {}", alpnConnection);
ALPN.put(alpnConnection.getSSLEngine(), this);
}
@Override
public void onClosed(Connection connection)
{
if (LOG.isDebugEnabled())
LOG.debug("onClosed {}", alpnConnection);
ALPN.remove(alpnConnection.getSSLEngine());
}
@Override
public List<String> protocols()
{
return alpnConnection.getProtocols();
}
@Override
public void unsupported()
{
if (LOG.isDebugEnabled())
LOG.debug("unsupported {}", alpnConnection);
ALPN.remove(alpnConnection.getSSLEngine());
alpnConnection.selected(null);
}
@Override
public void selected(String protocol)
{
alpnConnection.selected(protocol);
}
}
}

View File

@ -0,0 +1 @@
org.eclipse.jetty.alpn.java.client.OpenJDK8ClientALPNProcessor

View File

@ -0,0 +1,85 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.java.client;
import java.net.InetSocketAddress;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.Stream;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class OpenJDK8HTTP2Client
{
public static void main(String[] args) throws Exception
{
HTTP2Client client = new HTTP2Client();
SslContextFactory sslContextFactory = new SslContextFactory();
client.addBean(sslContextFactory);
client.start();
String host = "webtide.com";
int port = 443;
FuturePromise<Session> sessionPromise = new FuturePromise<>();
client.connect(sslContextFactory, new InetSocketAddress(host, port), new Session.Listener.Adapter(), sessionPromise);
Session session = sessionPromise.get(5, TimeUnit.SECONDS);
HttpFields requestFields = new HttpFields();
requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION);
MetaData.Request metaData = new MetaData.Request("GET", new HttpURI("https://" + host + ":" + port + "/"), HttpVersion.HTTP_2, requestFields);
HeadersFrame headersFrame = new HeadersFrame(metaData, null, true);
CountDownLatch latch = new CountDownLatch(1);
session.newStream(headersFrame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
{
@Override
public void onHeaders(Stream stream, HeadersFrame frame)
{
System.err.println(frame);
if (frame.isEndStream())
latch.countDown();
}
@Override
public void onData(Stream stream, DataFrame frame, Callback callback)
{
System.err.println(frame);
callback.succeeded();
if (frame.isEndStream())
latch.countDown();
}
});
latch.await(5, TimeUnit.SECONDS);
client.stop();
}
}

View File

@ -0,0 +1,2 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-parent</artifactId>
<version>9.4.8-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-alpn-openjdk8-server</artifactId>
<name>Jetty :: ALPN :: OpenJDK8 Server Implementation</name>
<properties>
<bundle-symbolic-name>${project.groupId}.alpn.conscrypt.server</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,104 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.openjdk8.server;
import java.util.Collections;
import java.util.List;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.alpn.server.ALPNServerConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class OpenJDK8ServerALPNProcessor implements ALPNProcessor.Server
{
private static final Logger LOG = Log.getLogger(OpenJDK8ServerALPNProcessor.class);
@Override
public void init()
{
if (JavaVersion.VERSION.getPlatform()!=8)
throw new IllegalStateException(this + " not applicable for java "+JavaVersion.VERSION);
if (ALPN.class.getClassLoader()!=null)
throw new IllegalStateException(ALPN.class.getName() + " must be on JVM boot classpath");
if (LOG.isDebugEnabled())
ALPN.debug = true;
}
@Override
public boolean appliesTo(SSLEngine sslEngine)
{
return sslEngine.getClass().getName().startsWith("sun.security.ssl.");
}
@Override
public void configure(SSLEngine sslEngine, Connection connection)
{
connection.addListener(new ALPNListener((ALPNServerConnection)connection));
}
private final class ALPNListener implements ALPN.ServerProvider, Connection.Listener
{
private final ALPNServerConnection alpnConnection;
private ALPNListener(ALPNServerConnection connection)
{
alpnConnection = connection;
}
@Override
public void onOpened(Connection connection)
{
if (LOG.isDebugEnabled())
LOG.debug("onOpened {}", alpnConnection);
ALPN.put(alpnConnection.getSSLEngine(), this);
}
@Override
public void onClosed(Connection connection)
{
if (LOG.isDebugEnabled())
LOG.debug("onClosed {}", alpnConnection);
ALPN.remove(alpnConnection.getSSLEngine());
}
@Override
public void unsupported()
{
if (LOG.isDebugEnabled())
LOG.debug("unsupported {}", alpnConnection);
alpnConnection.select(Collections.emptyList());
}
@Override
public String select(List<String> protocols) throws SSLException
{
if (LOG.isDebugEnabled())
LOG.debug("select {} {}", alpnConnection, protocols);
alpnConnection.select(protocols);
return alpnConnection.getProtocol();
}
}
}

View File

@ -0,0 +1 @@
org.eclipse.jetty.alpn.openjdk8.server.OpenJDK8ServerALPNProcessor

View File

@ -0,0 +1,66 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.alpn.openjdk8.server;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.HTTP2Cipher;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
/**
* Test server that verifies that the JDK 8 ALPN mechanism works.
*/
public class OpenJDK8HTTP2Server
{
public static void main(String... args) throws Exception
{
Server server = new Server();
HttpConfiguration httpsConfig = new HttpConfiguration();
httpsConfig.setSecureScheme("https");
httpsConfig.setSecurePort(8443);
httpsConfig.setSendXPoweredBy(true);
httpsConfig.setSendServerVersion(true);
httpsConfig.addCustomizer(new SecureRequestCustomizer());
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
HttpConnectionFactory http = new HttpConnectionFactory(httpsConfig);
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpsConfig);
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
alpn.setDefaultProtocol(http.getProtocol());
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
ServerConnector http2Connector = new ServerConnector(server, ssl, alpn, h2, http);
http2Connector.setPort(8443);
server.addConnector(http2Connector);
server.start();
}
}

View File

@ -0,0 +1,3 @@
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
#org.eclipse.jetty.LEVEL=DEBUG
#org.eclipse.jetty.alpn.LEVEL=DEBUG

View File

@ -59,12 +59,6 @@
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>

View File

@ -15,18 +15,9 @@
<Call name="addConnectionFactory">
<Arg>
<New id="alpn" class="org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory">
<Arg type="String">
<Property name="jetty.alpn.protocols" deprecated="alpn.protocols" default="" />
</Arg>
<Set name="defaultProtocol">
<Property name="jetty.alpn.defaultProtocol" deprecated="alpn.defaultProtocol" />
</Set>
<Arg name="protocols" type="String"><Property name="jetty.alpn.protocols" deprecated="alpn.protocols" default="" /></Arg>
<Set name="defaultProtocol"><Property name="jetty.alpn.defaultProtocol" deprecated="alpn.defaultProtocol" /></Set>
</New>
</Arg>
</Call>
<!-- ALPN debugging on System.err -->
<Set class="org.eclipse.jetty.alpn.ALPN" name="debug" type="boolean"><Property name="jetty.alpn.debug" default="false" /></Set>
</Configure>

View File

@ -0,0 +1,5 @@
[description]
Selects an ALPN (Application Layer Protocol Negotiation) implementation by java version.
[depend]
alpn-impl/alpn-${java.version.platform}

View File

@ -17,6 +17,9 @@ specific version of Java.
[depend]
alpn-impl/alpn-${java.version}
[lib]
lib/jetty-alpn-openjdk8-server-${jetty.version}.jar
[files]
lib/
lib/alpn/

View File

@ -3,7 +3,7 @@ Enables the ALPN (Application Layer Protocol Negotiation) TLS extension.
[depend]
ssl
alpn-impl/alpn-${java.version.platform}
alpn-impl
[lib]
lib/jetty-alpn-client-${jetty.version}.jar
@ -21,6 +21,3 @@ etc/jetty-alpn.xml
## Specifies what protocol to use when negotiation fails.
# jetty.alpn.defaultProtocol=http/1.1
## ALPN debug logging on System.err
# jetty.alpn.debug=false

View File

@ -24,7 +24,6 @@ import java.util.List;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import org.eclipse.jetty.alpn.ALPN;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Connector;
@ -32,24 +31,21 @@ import org.eclipse.jetty.server.NegotiatingServerConnection;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ALPNServerConnection extends NegotiatingServerConnection implements ALPN.ServerProvider
public class ALPNServerConnection extends NegotiatingServerConnection
{
private static final Logger LOG = Log.getLogger(ALPNServerConnection.class);
public ALPNServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
{
super(connector, endPoint, engine, protocols, defaultProtocol);
ALPN.put(engine, this);
}
@Override
public void unsupported()
{
select(Collections.emptyList());
}
@Override
public String select(List<String> clientProtocols)
public void select(List<String> clientProtocols)
{
SSLEngine sslEngine = getSSLEngine();
List<String> serverProtocols = getProtocols();
@ -70,7 +66,7 @@ public class ALPNServerConnection extends NegotiatingServerConnection implements
if (factory instanceof CipherDiscriminator && !((CipherDiscriminator)factory).isAcceptable(serverProtocol, tlsProtocol, tlsCipher))
{
if (LOG.isDebugEnabled())
LOG.debug("{} protocol {} not acceptable to {} for {}/{}", this, serverProtocol, factory, tlsProtocol, tlsCipher);
LOG.debug("Protocol {} not acceptable to {} for {}/{} on {}", serverProtocol, factory, tlsProtocol, tlsCipher, getEndPoint());
continue;
}
@ -87,21 +83,12 @@ public class ALPNServerConnection extends NegotiatingServerConnection implements
else
{
if (LOG.isDebugEnabled())
LOG.debug("{} could not negotiate protocol among client{} and server{}", this, clientProtocols, serverProtocols);
LOG.debug("Could not negotiate protocol from client{} and server{} on {}", clientProtocols, serverProtocols, getEndPoint());
throw new IllegalStateException();
}
}
if (LOG.isDebugEnabled())
LOG.debug("{} protocol selected {} among client{} and server{}", this, negotiated, clientProtocols, serverProtocols);
LOG.debug("Protocol selected {} from client{} and server{} on {}", negotiated, clientProtocols, serverProtocols, getEndPoint());
setProtocol(negotiated);
ALPN.remove(sslEngine);
return negotiated;
}
@Override
public void close()
{
ALPN.remove(getSSLEngine());
super.close();
}
}

View File

@ -18,6 +18,8 @@
package org.eclipse.jetty.alpn.server;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
@ -26,52 +28,82 @@ import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ssl.ALPNProcessor;
import org.eclipse.jetty.io.ssl.SslHandshakeListener;
import org.eclipse.jetty.io.ssl.ALPNProcessor.Server;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NegotiatingServerConnectionFactory;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ALPNServerConnectionFactory extends NegotiatingServerConnectionFactory implements SslHandshakeListener
public class ALPNServerConnectionFactory extends NegotiatingServerConnectionFactory
{
private final ALPNProcessor.Server alpnProcessor;
private static final Logger LOG = Log.getLogger(ALPNServerConnectionFactory.class);
public ALPNServerConnectionFactory(String protocols)
private final List<Server> processors = new ArrayList<>();
public ALPNServerConnectionFactory(@Name("protocols") String protocols)
{
this(protocols.trim().split(",", 0));
}
public ALPNServerConnectionFactory(@Name("protocols") String... protocols)
{
super("alpn", protocols);
checkProtocolNegotiationAvailable();
Iterator<ALPNProcessor.Server> processors = ServiceLoader.load(ALPNProcessor.Server.class).iterator();
alpnProcessor = processors.hasNext() ? processors.next() : ALPNProcessor.Server.NOOP;
}
public ALPNProcessor.Server getALPNProcessor()
{
return alpnProcessor;
IllegalStateException failure = new IllegalStateException("No Server ALPNProcessors!");
// Use a for loop on iterator so load exceptions can be caught and ignored
for (Iterator<Server> i = ServiceLoader.load(Server.class).iterator(); i.hasNext();)
{
Server processor;
try
{
processor = i.next();
}
catch(Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug(x);
failure.addSuppressed(x);
continue;
}
try
{
processor.init();
processors.add(processor);
}
catch (Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug("Could not initialize " + processor, x);
failure.addSuppressed(x);
}
}
if (LOG.isDebugEnabled())
{
LOG.debug("protocols: {}", Arrays.asList(protocols));
LOG.debug("processors: {}", processors);
}
if (processors.isEmpty())
throw failure;
}
@Override
protected AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
{
getALPNProcessor().configure(engine);
return new ALPNServerConnection(connector, endPoint, engine, protocols, defaultProtocol);
}
@Override
public void handshakeSucceeded(Event event)
{
if (alpnProcessor instanceof SslHandshakeListener)
((SslHandshakeListener)alpnProcessor).handshakeSucceeded(event);
}
@Override
public void handshakeFailed(Event event, Throwable failure)
{
if (alpnProcessor instanceof SslHandshakeListener)
((SslHandshakeListener)alpnProcessor).handshakeFailed(event, failure);
for (Server processor : processors)
{
if (processor.appliesTo(engine))
{
if (LOG.isDebugEnabled())
LOG.debug("{} for {} on {}", processor, engine, endPoint);
ALPNServerConnection connection = new ALPNServerConnection(connector, endPoint, engine, protocols, defaultProtocol);
processor.configure(engine, connection);
return connection;
}
}
throw new IllegalStateException("No ALPNProcessor for " + engine);
}
}

View File

@ -13,6 +13,10 @@
<modules>
<module>jetty-alpn-server</module>
<module>jetty-alpn-client</module>
<module>jetty-alpn-openjdk8-server</module>
<module>jetty-alpn-openjdk8-client</module>
<module>jetty-alpn-conscrypt-server</module>
<module>jetty-alpn-conscrypt-client</module>
</modules>
<profiles>
<profile>

View File

@ -35,10 +35,12 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.MultiReleaseJarFile;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@ -708,35 +710,10 @@ public class AnnotationParser
* @param nullInclusive if true, an empty pattern means all names match, if false, none match
* @throws Exception if unable to parse
*/
@Deprecated
public void parse (final Set<? extends Handler> handlers, ClassLoader loader, boolean visitParents, boolean nullInclusive) throws Exception
{
if (loader==null)
return;
if (!(loader instanceof URLClassLoader))
return; //can't extract classes?
final MultiException me = new MultiException();
JarScanner scanner = new JarScanner()
{
@Override
public void processEntry(URI jarUri, JarEntry entry)
{
try
{
parseJarEntry(handlers, Resource.newResource(jarUri), entry);
}
catch (Exception e)
{
me.add(new RuntimeException("Error parsing entry "+entry.getName()+" from jar "+ jarUri, e));
}
}
};
scanner.scan(null, loader, nullInclusive, visitParents);
me.ifExceptionThrow();
throw new UnsupportedOperationException();
}
/**
@ -836,32 +813,21 @@ public class AnnotationParser
if (LOG.isDebugEnabled())
LOG.debug("Scanning jar {}", jarResource);
//treat it as a jar that we need to open and scan all entries from
InputStream in = jarResource.getInputStream();
if (in==null)
return;
MultiException me = new MultiException();
try (JarInputStream jar_in = new JarInputStream(in))
// TODO do not force version 8 once ASM can scan 9
MultiReleaseJarFile jarFile = new MultiReleaseJarFile(jarResource.getFile(),8,false);
jarFile.stream().forEach(e->
{
JarEntry entry = jar_in.getNextJarEntry();
while (entry != null)
try
{
try
{
parseJarEntry(handlers, jarResource, entry);
}
catch (Exception e)
{
me.add(new RuntimeException("Error scanning entry " + entry.getName() + " from jar " + jarResource, e));
}
entry = jar_in.getNextJarEntry();
parseJarEntry(handlers, jarResource, e);
}
}
catch (Exception e)
{
me.add(new RuntimeException("Error scanning jar " + jarResource, e));
}
catch (Exception ex)
{
me.add(new RuntimeException("Error scanning entry " + e.getName() + " from jar " + jarResource, ex));
}
});
me.ifExceptionThrow();
}
@ -871,11 +837,10 @@ public class AnnotationParser
* Parse a single entry in a jar file
*
* @param handlers the handlers to look for classes in
* @param jar the jar resource to parse
* @param entry the entry in the jar resource to parse
* @param entry the entry in the potentially MultiRelease jar resource to parse
* @throws Exception if unable to parse
*/
protected void parseJarEntry (Set<? extends Handler> handlers, Resource jar, JarEntry entry) throws Exception
protected void parseJarEntry (Set<? extends Handler> handlers, Resource jar, MultiReleaseJarFile.VersionedJarEntry entry) throws Exception
{
if (jar == null || entry == null)
return;
@ -890,11 +855,10 @@ public class AnnotationParser
if (isValidClassFileName(name) && isValidClassFilePath(name))
{
String shortName = name.replace('/', '.').substring(0,name.length()-6);
Resource clazz = Resource.newResource("jar:"+jar.getURI()+"!/"+name);
addParsedClass(shortName, clazz);
addParsedClass(shortName, Resource.newResource("jar:"+jar.getURI()+"!/"+entry.getNameInJar()));
if (LOG.isDebugEnabled())
LOG.debug("Scanning class from jar {}", clazz);
try (InputStream is = clazz.getInputStream())
LOG.debug("Scanning class from jar {}!/{}", jar, entry);
try (InputStream is = entry.getInputStream())
{
scanClass(handlers, jar, is);
}
@ -979,57 +943,6 @@ public class AnnotationParser
if (path == null || path.length()==0)
return false;
if (path.startsWith("META-INF/versions/"))
{
// Handle JEP 238 - Multi-Release Jars
if (JVM_MAJOR_VER < 9)
{
if (LOG.isDebugEnabled())
{
LOG.debug("JEP-238 Multi-Release JAR not supported on Java " +
System.getProperty("java.version") + ": " + path);
}
return false;
}
// Safety check for ASM bytecode support level.
// When ASM 6.0 is integrated, the below will start to work.
if (ASM_OPCODE_VERSION <= Opcodes.ASM5)
{
// Cannot scan Java 9 classes with ASM version 5
if (LOG.isDebugEnabled())
{
LOG.debug("Unable to scan newer Java bytecode (Java 9?) with ASM 5 (skipping): " + path);
}
return false;
}
int idxStart = "META-INF/versions/".length();
int idxEnd = path.indexOf('/', idxStart + 1);
try
{
int pathVersion = Integer.parseInt(path.substring(idxStart, idxEnd));
if (pathVersion < JVM_MAJOR_VER)
{
if (LOG.isDebugEnabled())
{
LOG.debug("JEP-238 Multi-Release JAR version " + pathVersion +
" not supported on Java " + System.getProperty("java.version") +
": " + path);
}
return false;
}
}
catch (NumberFormatException e)
{
if (LOG.isDebugEnabled())
{
LOG.debug("Not a valid JEP-238 Multi-Release path: " + path);
}
return false;
}
}
// skip any classfiles that are in a hidden directory
if (path.startsWith(".") || path.contains("/."))
{

View File

@ -207,7 +207,7 @@ INFO : logging-log4j initialized in ${jetty.base}/start.d/logging-log4j.ini
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/log4j
COPY : /Users/chris/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar to ${jetty.base}/lib/log4j/log4j-1.2.17.jar
COPY : /Users/admin/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar to ${jetty.base}/lib/log4j/log4j-1.2.17.jar
MKDIR : ${jetty.base}/resources
COPY : ${jetty.home}/modules/log4j-impl/resources/log4j.xml to ${jetty.base}/resources/log4j.xml
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-log4j12-1.7.21.jar

View File

@ -123,49 +123,49 @@ COPY : ${jetty.home}/modules/jul-impl/etc/java-util-logging.properties to ${jet
MKDIR : ${jetty.base}/lib/slf4j
DOWNLD: http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar to ${jetty.base}/lib/slf4j/slf4j-api-1.7.21.jar
MKDIR : ${jetty.base}/lib/gcloud
COPY : /Users/chris/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar to ${jetty.base}/lib/gcloud/aopalliance-1.0.jar
COPY : /Users/chris/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.1.3/jackson-core-2.1.3.jar to ${jetty.base}/lib/gcloud/jackson-core-2.1.3.jar
COPY : /Users/chris/.m2/repository/com/google/api-client/google-api-client-appengine/1.21.0/google-api-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-api-client-appengine-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/api-client/google-api-client/1.20.0/google-api-client-1.20.0.jar to ${jetty.base}/lib/gcloud/google-api-client-1.20.0.jar
COPY : /Users/chris/.m2/repository/com/google/api-client/google-api-client-servlet/1.21.0/google-api-client-servlet-1.21.0.jar to ${jetty.base}/lib/gcloud/google-api-client-servlet-1.21.0.jar
COPY : /Users/admin/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar to ${jetty.base}/lib/gcloud/aopalliance-1.0.jar
COPY : /Users/admin/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.1.3/jackson-core-2.1.3.jar to ${jetty.base}/lib/gcloud/jackson-core-2.1.3.jar
COPY : /Users/admin/.m2/repository/com/google/api-client/google-api-client-appengine/1.21.0/google-api-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-api-client-appengine-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/api-client/google-api-client/1.20.0/google-api-client-1.20.0.jar to ${jetty.base}/lib/gcloud/google-api-client-1.20.0.jar
COPY : /Users/admin/.m2/repository/com/google/api-client/google-api-client-servlet/1.21.0/google-api-client-servlet-1.21.0.jar to ${jetty.base}/lib/gcloud/google-api-client-servlet-1.21.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/api/gax/0.0.21/gax-0.0.21.jar to ${jetty.base}/lib/gcloud/gax-0.0.21.jar
COPY : /Users/chris/.m2/repository/com/google/api/grpc/grpc-google-common-protos/0.1.0/grpc-google-common-protos-0.1.0.jar to ${jetty.base}/lib/gcloud/grpc-google-common-protos-0.1.0.jar
COPY : /Users/chris/.m2/repository/com/google/api/grpc/grpc-google-iam-v1/0.1.0/grpc-google-iam-v1-0.1.0.jar to ${jetty.base}/lib/gcloud/grpc-google-iam-v1-0.1.0.jar
COPY : /Users/chris/.m2/repository/com/google/auth/google-auth-library-credentials/0.3.1/google-auth-library-credentials-0.3.1.jar to ${jetty.base}/lib/gcloud/google-auth-library-credentials-0.3.1.jar
COPY : /Users/chris/.m2/repository/com/google/auth/google-auth-library-oauth2-http/0.3.1/google-auth-library-oauth2-http-0.3.1.jar to ${jetty.base}/lib/gcloud/google-auth-library-oauth2-http-0.3.1.jar
COPY : /Users/admin/.m2/repository/com/google/api/grpc/grpc-google-common-protos/0.1.0/grpc-google-common-protos-0.1.0.jar to ${jetty.base}/lib/gcloud/grpc-google-common-protos-0.1.0.jar
COPY : /Users/admin/.m2/repository/com/google/api/grpc/grpc-google-iam-v1/0.1.0/grpc-google-iam-v1-0.1.0.jar to ${jetty.base}/lib/gcloud/grpc-google-iam-v1-0.1.0.jar
COPY : /Users/admin/.m2/repository/com/google/auth/google-auth-library-credentials/0.3.1/google-auth-library-credentials-0.3.1.jar to ${jetty.base}/lib/gcloud/google-auth-library-credentials-0.3.1.jar
COPY : /Users/admin/.m2/repository/com/google/auth/google-auth-library-oauth2-http/0.3.1/google-auth-library-oauth2-http-0.3.1.jar to ${jetty.base}/lib/gcloud/google-auth-library-oauth2-http-0.3.1.jar
DOWNLD: http://central.maven.org/maven2/com/google/auto/value/auto-value/1.2/auto-value-1.2.jar to ${jetty.base}/lib/gcloud/auto-value-1.2.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/datastore/datastore-v1-proto-client/1.3.0/datastore-v1-proto-client-1.3.0.jar to ${jetty.base}/lib/gcloud/datastore-v1-proto-client-1.3.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/datastore/datastore-v1-protos/1.3.0/datastore-v1-protos-1.3.0.jar to ${jetty.base}/lib/gcloud/datastore-v1-protos-1.3.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/google-cloud-core/0.5.1/google-cloud-core-0.5.1.jar to ${jetty.base}/lib/gcloud/google-cloud-core-0.5.0.jar
DOWNLD: http://central.maven.org/maven2/com/google/cloud/google-cloud-datastore/0.5.1/google-cloud-datastore-0.5.1.jar to ${jetty.base}/lib/gcloud/google-cloud-datastore-0.5.1.jar
COPY : /Users/chris/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar to ${jetty.base}/lib/gcloud/jsr305-1.3.9.jar
COPY : /Users/chris/.m2/repository/com/google/code/gson/gson/2.3/gson-2.3.jar to ${jetty.base}/lib/gcloud/gson-2.3.jar
COPY : /Users/chris/.m2/repository/com/google/guava/guava/19.0/guava-19.0.jar to ${jetty.base}/lib/gcloud/guava-19.0.jar
COPY : /Users/chris/.m2/repository/com/google/http-client/google-http-client-appengine/1.21.0/google-http-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-appengine-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/http-client/google-http-client-jackson2/1.19.0/google-http-client-jackson2-1.19.0.jar to ${jetty.base}/lib/gcloud/google-http-client-jackson2-1.19.0.jar
COPY : /Users/chris/.m2/repository/com/google/http-client/google-http-client-jackson/1.21.0/google-http-client-jackson-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-jackson-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/http-client/google-http-client/1.21.0/google-http-client-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/http-client/google-http-client-jdo/1.21.0/google-http-client-jdo-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-jdo-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/http-client/google-http-client-protobuf/1.20.0/google-http-client-protobuf-1.20.0.jar to ${jetty.base}/lib/gcloud/google-http-client-protobuf-1.20.0.jar
COPY : /Users/chris/.m2/repository/com/google/inject/guice/4.0/guice-4.0.jar to ${jetty.base}/lib/gcloud/guice-4.0.jar
COPY : /Users/chris/.m2/repository/com/google/oauth-client/google-oauth-client-appengine/1.21.0/google-oauth-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-oauth-client-appengine-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/oauth-client/google-oauth-client/1.21.0/google-oauth-client-1.21.0.jar to ${jetty.base}/lib/gcloud/google-oauth-client-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/oauth-client/google-oauth-client-servlet/1.21.0/google-oauth-client-servlet-1.21.0.jar to ${jetty.base}/lib/gcloud/google-oauth-client-servlet-1.21.0.jar
COPY : /Users/chris/.m2/repository/com/google/protobuf/protobuf-java/3.0.0/protobuf-java-3.0.0.jar to ${jetty.base}/lib/gcloud/protobuf-java-3.0.0.jar
COPY : /Users/chris/.m2/repository/com/google/protobuf/protobuf-java-util/3.0.0/protobuf-java-util-3.0.0.jar to ${jetty.base}/lib/gcloud/protobuf-java-util-3.0.0.jar
COPY : /Users/chris/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar to ${jetty.base}/lib/gcloud/commons-codec-1.3.jar
COPY : /Users/chris/.m2/repository/io/grpc/grpc-context/1.0.1/grpc-context-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-context-1.0.1.jar
COPY : /Users/chris/.m2/repository/io/grpc/grpc-core/1.0.1/grpc-core-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-core-1.0.1.jar
COPY : /Users/chris/.m2/repository/io/grpc/grpc-protobuf/1.0.1/grpc-protobuf-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-protobuf-1.0.1.jar
COPY : /Users/chris/.m2/repository/io/grpc/grpc-protobuf-lite/1.0.1/grpc-protobuf-lite-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-protobuf-lite-1.0.1.jar
COPY : /Users/chris/.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar to ${jetty.base}/lib/gcloud/javax.inject-1.jar
COPY : /Users/chris/.m2/repository/javax/jdo/jdo2-api/2.3-eb/jdo2-api-2.3-eb.jar to ${jetty.base}/lib/gcloud/jdo2-api-2.3-eb.jar
COPY : /Users/chris/.m2/repository/javax/transaction/transaction-api/1.1/transaction-api-1.1.jar to ${jetty.base}/lib/gcloud/transaction-api-1.1.jar
COPY : /Users/chris/.m2/repository/joda-time/joda-time/2.9.2/joda-time-2.9.2.jar to ${jetty.base}/lib/gcloud/joda-time-2.9.2.jar
COPY : /Users/chris/.m2/repository/org/apache/httpcomponents/httpclient/4.0.1/httpclient-4.0.1.jar to ${jetty.base}/lib/gcloud/httpclient-4.0.1.jar
COPY : /Users/chris/.m2/repository/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar to ${jetty.base}/lib/gcloud/httpcore-4.0.1.jar
COPY : /Users/chris/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.11/jackson-core-asl-1.9.11.jar to ${jetty.base}/lib/gcloud/jackson-core-asl-1.9.11.jar
COPY : /Users/chris/.m2/repository/org/json/json/20151123/json-20151123.jar to ${jetty.base}/lib/gcloud/json-20151123.jar
COPY : /Users/admin/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar to ${jetty.base}/lib/gcloud/jsr305-1.3.9.jar
COPY : /Users/admin/.m2/repository/com/google/code/gson/gson/2.3/gson-2.3.jar to ${jetty.base}/lib/gcloud/gson-2.3.jar
COPY : /Users/admin/.m2/repository/com/google/guava/guava/19.0/guava-19.0.jar to ${jetty.base}/lib/gcloud/guava-19.0.jar
COPY : /Users/admin/.m2/repository/com/google/http-client/google-http-client-appengine/1.21.0/google-http-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-appengine-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/http-client/google-http-client-jackson2/1.19.0/google-http-client-jackson2-1.19.0.jar to ${jetty.base}/lib/gcloud/google-http-client-jackson2-1.19.0.jar
COPY : /Users/admin/.m2/repository/com/google/http-client/google-http-client-jackson/1.21.0/google-http-client-jackson-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-jackson-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/http-client/google-http-client/1.21.0/google-http-client-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/http-client/google-http-client-jdo/1.21.0/google-http-client-jdo-1.21.0.jar to ${jetty.base}/lib/gcloud/google-http-client-jdo-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/http-client/google-http-client-protobuf/1.20.0/google-http-client-protobuf-1.20.0.jar to ${jetty.base}/lib/gcloud/google-http-client-protobuf-1.20.0.jar
COPY : /Users/admin/.m2/repository/com/google/inject/guice/4.0/guice-4.0.jar to ${jetty.base}/lib/gcloud/guice-4.0.jar
COPY : /Users/admin/.m2/repository/com/google/oauth-client/google-oauth-client-appengine/1.21.0/google-oauth-client-appengine-1.21.0.jar to ${jetty.base}/lib/gcloud/google-oauth-client-appengine-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/oauth-client/google-oauth-client/1.21.0/google-oauth-client-1.21.0.jar to ${jetty.base}/lib/gcloud/google-oauth-client-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/oauth-client/google-oauth-client-servlet/1.21.0/google-oauth-client-servlet-1.21.0.jar to ${jetty.base}/lib/gcloud/google-oauth-client-servlet-1.21.0.jar
COPY : /Users/admin/.m2/repository/com/google/protobuf/protobuf-java/3.0.0/protobuf-java-3.0.0.jar to ${jetty.base}/lib/gcloud/protobuf-java-3.0.0.jar
COPY : /Users/admin/.m2/repository/com/google/protobuf/protobuf-java-util/3.0.0/protobuf-java-util-3.0.0.jar to ${jetty.base}/lib/gcloud/protobuf-java-util-3.0.0.jar
COPY : /Users/admin/.m2/repository/commons-codec/commons-codec/1.3/commons-codec-1.3.jar to ${jetty.base}/lib/gcloud/commons-codec-1.3.jar
COPY : /Users/admin/.m2/repository/io/grpc/grpc-context/1.0.1/grpc-context-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-context-1.0.1.jar
COPY : /Users/admin/.m2/repository/io/grpc/grpc-core/1.0.1/grpc-core-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-core-1.0.1.jar
COPY : /Users/admin/.m2/repository/io/grpc/grpc-protobuf/1.0.1/grpc-protobuf-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-protobuf-1.0.1.jar
COPY : /Users/admin/.m2/repository/io/grpc/grpc-protobuf-lite/1.0.1/grpc-protobuf-lite-1.0.1.jar to ${jetty.base}/lib/gcloud/grpc-protobuf-lite-1.0.1.jar
COPY : /Users/admin/.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar to ${jetty.base}/lib/gcloud/javax.inject-1.jar
COPY : /Users/admin/.m2/repository/javax/jdo/jdo2-api/2.3-eb/jdo2-api-2.3-eb.jar to ${jetty.base}/lib/gcloud/jdo2-api-2.3-eb.jar
COPY : /Users/admin/.m2/repository/javax/transaction/transaction-api/1.1/transaction-api-1.1.jar to ${jetty.base}/lib/gcloud/transaction-api-1.1.jar
COPY : /Users/admin/.m2/repository/joda-time/joda-time/2.9.2/joda-time-2.9.2.jar to ${jetty.base}/lib/gcloud/joda-time-2.9.2.jar
COPY : /Users/admin/.m2/repository/org/apache/httpcomponents/httpclient/4.0.1/httpclient-4.0.1.jar to ${jetty.base}/lib/gcloud/httpclient-4.0.1.jar
COPY : /Users/admin/.m2/repository/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar to ${jetty.base}/lib/gcloud/httpcore-4.0.1.jar
COPY : /Users/admin/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.11/jackson-core-asl-1.9.11.jar to ${jetty.base}/lib/gcloud/jackson-core-asl-1.9.11.jar
COPY : /Users/admin/.m2/repository/org/json/json/20151123/json-20151123.jar to ${jetty.base}/lib/gcloud/json-20151123.jar
DOWNLD: http://central.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21.jar to ${jetty.base}/lib/slf4j/jcl-over-slf4j-1.7.21.jar
COPY : ${jetty.home}/modules/gcloud/index.yaml to ${jetty.base}/etc/index.yaml
INFO : Base directory was modified

View File

@ -24,10 +24,11 @@ When using the Jetty distribution, you will first need to enable the `session-st
[source, screen, subs="{sub-order}"]
----
mb-olamy:tmp-base olamy$ java -jar ../start.jar --create-startd
$ java -jar ../start.jar --create-startd
MKDIR : ${jetty.base}/start.d
INFO : Base directory was modified
mb-olamy:tmp-base olamy$ java -jar ../start.jar --add-to-start=session-store-hazelcast-remote
$ java -jar ../start.jar --add-to-start=session-store-hazelcast-remote
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
@ -44,11 +45,11 @@ Proceed (y/N)? y
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-hazelcast-remote initialized in ${jetty.base}/start.d/session-store-hazelcast-remote.ini
MKDIR : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : ${jetty.base}/lib/hazelcast
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
INFO : Base directory was modified
----
@ -112,10 +113,10 @@ To enable this you will first need to enable the `session-store-hazelcast-embedd
[source, screen, subs="{sub-order}"]
----
mb-olamy:tmp-base olamy$ java -jar ../start.jar --create-startd
$ java -jar ../start.jar --create-startd
MKDIR : ${jetty.base}/start.d
INFO : Base directory was modified
mb-olamy:tmp-base olamy$ java -jar ../start.jar --add-to-start=session-store-hazelcast-embedded
$ java -jar ../start.jar --add-to-start=session-store-hazelcast-embedded
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
@ -132,11 +133,11 @@ Proceed (y/N)? y
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-hazelcast-embedded initialized in ${jetty.base}/start.d/session-store-hazelcast-embedded.ini
MKDIR : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : ${jetty.base}/lib/hazelcast
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/admin/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
----
Doing this enables the embedded Hazelcast Session module and any dependent modules or files needed for it to run on the server.

View File

@ -22,6 +22,11 @@
When using the Jetty distribution, you will first need to enable the `session-store-infinispan-remote` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line.
____
[IMPORTANT]
If you are running Jetty with JDK 9 or greater, enable `session-store-infinispan-remote-910.mod` instead.
____
[source, screen, subs="{sub-order}"]
----
$ java -jar ../start.jar --create-startd
@ -106,6 +111,11 @@ ____
During testing, it can be helpful to run an in-process instance of Infinispan.
To enable this you will first need to enable the `session-store-infinispan-embedded` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line.
____
[IMPORTANT]
If you are running Jetty with JDK 9 or greater, enable `session-store-infinispan-embedded-910.mod` instead.
____
[source, screen, subs="{sub-order}"]
----
java -jar ../start.jar --add-to-start=session-store-infinispan-embedded

View File

@ -17,7 +17,7 @@
[[sessions-usecases]]
=== Use Cases
===== Clustering with a Sticky Load Balancer
==== Clustering with a Sticky Load Balancer
Preferably, your cluster will utilize a sticky load balancer.
This will route requests for the same Session to the same Jetty instance.
@ -36,7 +36,7 @@ With this policy, Session objects will remain in the cache until they either exp
If you have a high likelihood of simultaneous requests for the same session object, then the `EVICT_ON_SESSION_EXIT` policy will ensure the Session object stays in the cache as long as it is needed.
===== Clustering Without a Sticky Load Balancer
==== Clustering Without a Sticky Load Balancer
Without a sticky load balancer requests for the same session may arrive on any node in the cluster.
This means it is likely that the copy of the Session object in any `SessionCache` is likely to be out-of-date, as the Session was probably last accessed on a different node.
@ -52,7 +52,7 @@ Again, due to the lack of Session transactionality, the ordering outcome of writ
As the Session is cached while at least one request is accessing it, it is possible for multiple simultaneous requests to share the same Session object.
===== Handling corrupted or unloadable session data
==== Handling corrupted or unloadable session data
For various reasons it might not be possible for the `SessionDataStore` to re-read a stored session.
One scenario is that the session stores a serialized object in it's attributes, and after a redeployment there in an incompatible class change.

View File

@ -115,8 +115,8 @@ Jetty Environment:
Config Search Order:
--------------------
<command-line>
${jetty.base} -> /home/user/jetty-distribution-9.4.1.v20170120/demo-base
${jetty.home} -> /home/user/Desktop/jetty-distribution-9.4.1.v20170120
${jetty.base} -> /home/user/jetty-distribution-{VERSION}/demo-base
${jetty.home} -> /home/user/Desktop/jetty-distribution-{VERSION}
JVM Arguments:
--------------
@ -152,26 +152,26 @@ Jetty Server Classpath:
Version Information on 42 entries in the classpath.
Note: order presented here is how they would appear on the classpath.
changes to the --module=name command line options will be reflected here.
0: {VERSION} | ${jetty.home}/lib/jetty-client-{VERSION}.jar
0: {VERSION} | ${jetty.home}/lib/jetty-client-{VERSION}.jar
1: 1.4.1.v201005082020 | ${jetty.base}/lib/ext/javax.mail.glassfish-1.4.1.v201005082020.jar
2: {VERSION} | ${jetty.base}/lib/ext/test-mock-resources-{VERSION}.jar
2: {VERSION} | ${jetty.base}/lib/ext/test-mock-resources-{VERSION}.jar
3: (dir) | ${jetty.home}/resources
4: 3.1.0 | ${jetty.home}/lib/servlet-api-3.1.jar
5: 3.1.RC0 | ${jetty.home}/lib/jetty-schemas-3.1.jar
6: {VERSION} | ${jetty.home}/lib/jetty-http-{VERSION}.jar
7: {VERSION} | ${jetty.home}/lib/jetty-continuation-{VERSION}.jar
8: {VERSION} | ${jetty.home}/lib/jetty-server-{VERSION}.jar
9: {VERSION} | ${jetty.home}/lib/jetty-xml-{VERSION}.jar
10: {VERSION} | ${jetty.home}/lib/jetty-util-{VERSION}.jar
11: {VERSION} | ${jetty.home}/lib/jetty-io-{VERSION}.jar
12: {VERSION} | ${jetty.home}/lib/jetty-jaas-{VERSION}.jar
13: {VERSION} | ${jetty.home}/lib/jetty-jndi-{VERSION}.jar
6: {VERSION} | ${jetty.home}/lib/jetty-http-{VERSION}.jar
7: {VERSION} | ${jetty.home}/lib/jetty-continuation-{VERSION}.jar
8: {VERSION} | ${jetty.home}/lib/jetty-server-{VERSION}.jar
9: {VERSION} | ${jetty.home}/lib/jetty-xml-{VERSION}.jar
10: {VERSION} | ${jetty.home}/lib/jetty-util-{VERSION}.jar
11: {VERSION} | ${jetty.home}/lib/jetty-io-{VERSION}.jar
12: {VERSION} | ${jetty.home}/lib/jetty-jaas-{VERSION}.jar
13: {VERSION} | ${jetty.home}/lib/jetty-jndi-{VERSION}.jar
14: 1.1.0.v201105071233 | ${jetty.home}/lib/jndi/javax.activation-1.1.0.v201105071233.jar
15: 1.4.1.v201005082020 | ${jetty.home}/lib/jndi/javax.mail.glassfish-1.4.1.v201005082020.jar
16: 1.2 | ${jetty.home}/lib/jndi/javax.transaction-api-1.2.jar
17: {VERSION} | ${jetty.home}/lib/jetty-rewrite-{VERSION}.jar
18: {VERSION} | ${jetty.home}/lib/jetty-security-{VERSION}.jar
19: {VERSION} | ${jetty.home}/lib/jetty-servlet-{VERSION}.jar
17: {VERSION} | ${jetty.home}/lib/jetty-rewrite-{VERSION}.jar
18: {VERSION} | ${jetty.home}/lib/jetty-security-{VERSION}.jar
19: {VERSION} | ${jetty.home}/lib/jetty-servlet-{VERSION}.jar
20: 3.0.0 | ${jetty.home}/lib/jsp/javax.el-3.0.0.jar
21: 1.2.0.v201105211821 | ${jetty.home}/lib/jsp/javax.servlet.jsp.jstl-1.2.0.v201105211821.jar
22: 2.3.2 | ${jetty.home}/lib/jsp/javax.servlet.jsp-2.3.2.jar
@ -179,21 +179,21 @@ Note: order presented here is how they would appear on the classpath.
24: 2.3.3 | ${jetty.home}/lib/jsp/jetty-jsp-jdt-2.3.3.jar
25: 1.2.0.v201112081803 | ${jetty.home}/lib/jsp/org.apache.taglibs.standard.glassfish-1.2.0.v201112081803.jar
26: 3.8.2.v20130121-145325 | ${jetty.home}/lib/jsp/org.eclipse.jdt.core-3.8.2.v20130121.jar
27: {VERSION} | ${jetty.home}/lib/jetty-plus-{VERSION}.jar
28: {VERSION} | ${jetty.home}/lib/jetty-webapp-{VERSION}.jar
29: {VERSION} | ${jetty.home}/lib/jetty-annotations-{VERSION}.jar
27: {VERSION} | ${jetty.home}/lib/jetty-plus-{VERSION}.jar
28: {VERSION} | ${jetty.home}/lib/jetty-webapp-{VERSION}.jar
29: {VERSION} | ${jetty.home}/lib/jetty-annotations-{VERSION}.jar
30: 4.1 | ${jetty.home}/lib/annotations/asm-4.1.jar
31: 4.1 | ${jetty.home}/lib/annotations/asm-commons-4.1.jar
32: 1.2 | ${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar
33: {VERSION} | ${jetty.home}/lib/jetty-deploy-{VERSION}.jar
33: {VERSION} | ${jetty.home}/lib/jetty-deploy-{VERSION}.jar
34: 1.0 | ${jetty.home}/lib/websocket/javax.websocket-api-1.0.jar
35: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-client-impl-{VERSION}.jar
36: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-server-impl-{VERSION}.jar
37: {VERSION} | ${jetty.home}/lib/websocket/websocket-api-{VERSION}.jar
38: {VERSION} | ${jetty.home}/lib/websocket/websocket-client-{VERSION}.jar
39: {VERSION} | ${jetty.home}/lib/websocket/websocket-common-{VERSION}.jar
40: {VERSION} | ${jetty.home}/lib/websocket/websocket-server-{VERSION}.jar
41: {VERSION} | ${jetty.home}/lib/websocket/websocket-servlet-{VERSION}.jar
35: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-client-impl-{VERSION}.jar
36: {VERSION} | ${jetty.home}/lib/websocket/javax-websocket-server-impl-{VERSION}.jar
37: {VERSION} | ${jetty.home}/lib/websocket/websocket-api-{VERSION}.jar
38: {VERSION} | ${jetty.home}/lib/websocket/websocket-client-{VERSION}.jar
39: {VERSION} | ${jetty.home}/lib/websocket/websocket-common-{VERSION}.jar
40: {VERSION} | ${jetty.home}/lib/websocket/websocket-server-{VERSION}.jar
41: {VERSION} | ${jetty.home}/lib/websocket/websocket-servlet-{VERSION}.jar
Jetty Active XMLs:
------------------

View File

@ -20,7 +20,7 @@
This document provides an overview of how to configure SSL and TLS for Jetty.
[[configuring-jetty-for-ssl]]
===== Configuring Jetty for SSL
==== Configuring Jetty for SSL
To configure Jetty for SSL, complete the tasks in the following sections:

View File

@ -26,8 +26,8 @@ To start Jetty on the default port of 8080, run the following command:
2015-06-04 10:50:44.806:INFO::main: Logging initialized @334ms
2015-06-04 10:50:44.858:WARN:oejs.HomeBaseWarning:main: This instance of Jetty is not running from a separate {jetty.base} directory, this is not recommended. See documentation at http://www.eclipse.org/jetty/documentation/current/startup.html
2015-06-04 10:50:44.995:INFO:oejs.Server:main: jetty-9.3.0.v20150601
2015-06-04 10:50:45.012:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///opt/jetty-distribution-9.3.0.v20150601/webapps/] at interval 1
2015-06-04 10:50:44.995:INFO:oejs.Server:main: jetty-{VERSION}
2015-06-04 10:50:45.012:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///opt/jetty-distribution-{VERSION}/webapps/] at interval 1
2015-06-04 10:50:45.030:INFO:oejs.ServerConnector:main: Started ServerConnector@19dfb72a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2015-06-04 10:50:45.030:INFO:oejs.Server:main: Started @558ms
----
@ -57,13 +57,13 @@ Within the standard Jetty distribution there is the `demo-base` directory, which
2017-08-16 16:55:15.571:INFO::main: Logging initialized @521ms to org.eclipse.jetty.util.log.StdErrLog
2017-08-16 16:55:15.907:WARN::main: demo test-realm is deployed. DO NOT USE IN PRODUCTION!
2017-08-16 16:55:15.910:INFO:oejs.Server:main: jetty-9.4.7-SNAPSHOT
2017-08-16 16:55:15.931:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/webapps/] at interval 1
2017-08-16 16:55:15.910:INFO:oejs.Server:main: jetty-{VERSION}
2017-08-16 16:55:15.931:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/jetty-distribution-{VERSION}/demo-base/webapps/] at interval 1
2017-08-16 16:55:16.151:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=50ms
2017-08-16 16:55:16.369:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2017-08-16 16:55:16.369:INFO:oejs.session:main: No SessionScavenger set, using defaults
2017-08-16 16:55:16.370:INFO:oejs.session:main: Scavenging every 660000ms
2017-08-16 16:55:16.416:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@7113b13f{/,file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/webapps/ROOT/,AVAILABLE}{/ROOT}
2017-08-16 16:55:16.416:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@7113b13f{/,file:///tmp/jetty-distribution-{VERSION}/demo-base/webapps/ROOT/,AVAILABLE}{/ROOT}
2017-08-16 16:55:16.625:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=82ms
2017-08-16 16:55:16.631:WARN::main: test webapp is deployed. DO NOT USE IN PRODUCTION!
2017-08-16 16:55:16.751:INFO:oejsh.ManagedAttributeListener:main: update PushFilter null->org.eclipse.jetty.servlets.PushCacheFilter@1a677343 on o.e.j.w.WebAppContext@2d7275fc{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-7157753932050220016.dir/webapp/,STARTING}{/test.war}
@ -72,7 +72,7 @@ Within the standard Jetty distribution there is the `demo-base` directory, which
2017-08-16 16:55:16.809:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@2d7275fc{/test,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test.war-_test-any-7157753932050220016.dir/webapp/,AVAILABLE}{/test.war}
2017-08-16 16:55:16.816:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.MovedContextHandler@7c9d8e2{/oldContextPath,null,AVAILABLE}
2017-08-16 16:55:16.854:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=23ms
2017-08-16 16:55:16.891:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@69453e37{/doc,file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/webapps/doc/,AVAILABLE}{/doc}
2017-08-16 16:55:16.891:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@69453e37{/doc,file:///tmp/jetty-distribution-{VERSION}/demo-base/webapps/doc/,AVAILABLE}{/doc}
2017-08-16 16:55:16.942:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=25ms
2017-08-16 16:55:16.945:WARN::main: test-jaas webapp is deployed. DO NOT USE IN PRODUCTION!
2017-08-16 16:55:16.983:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@4e3958e7{/test-jaas,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-jaas.war-_test-jaas-any-6953571893682159674.dir/webapp/,AVAILABLE}{/test-jaas.war}
@ -81,15 +81,15 @@ Within the standard Jetty distribution there is the `demo-base` directory, which
2017-08-16 16:55:17.192:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1d8bd0de{/test-jndi,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-jndi.war-_test-jndi-any-1246461885510956986.dir/webapp/,AVAILABLE}{/test-jndi.war}
2017-08-16 16:55:17.307:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=53ms
2017-08-16 16:55:17.310:WARN::main: test-spec webapp is deployed. DO NOT USE IN PRODUCTION!
2017-08-16 16:55:17.388:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@51dcb805{/test-spec,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-3750193079644252256.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-3750193079644252256.dir/webapp/WEB-INF/lib/test-web-fragment-9.4.7-SNAPSHOT.jar!/META-INF/resources],AVAILABLE}{/test-spec.war}
2017-08-16 16:55:17.388:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@51dcb805{/test-spec,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-3750193079644252256.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-test-spec.war-_test-spec-any-3750193079644252256.dir/webapp/WEB-INF/lib/test-web-fragment-{VERSION}.jar!/META-INF/resources],AVAILABLE}{/test-spec.war}
2017-08-16 16:55:17.490:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=53ms
2017-08-16 16:55:17.493:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
2017-08-16 16:55:17.516:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1de76cc7{/async-rest,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-8972552397332323832.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-8972552397332323832.dir/webapp/WEB-INF/lib/example-async-rest-jar-9.4.7-SNAPSHOT.jar!/META-INF/resources],AVAILABLE}{/async-rest.war}
2017-08-16 16:55:17.516:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1de76cc7{/async-rest,[file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-8972552397332323832.dir/webapp/, jar:file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-async-rest.war-_async-rest-any-8972552397332323832.dir/webapp/WEB-INF/lib/example-async-rest-jar-{VERSION}.jar!/META-INF/resources],AVAILABLE}{/async-rest.war}
2017-08-16 16:55:17.643:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=83ms
2017-08-16 16:55:17.921:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@242b836{/proxy,file:///private/var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/jetty-0.0.0.0-8080-javadoc-proxy.war-_javadoc-proxy-any-4521643038409884891.dir/webapp/,AVAILABLE}{/javadoc-proxy.war}
2017-08-16 16:55:17.936:INFO:oejs.AbstractConnector:main: Started ServerConnector@6f15d60e{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2017-08-16 16:55:17.944:INFO:oejus.SslContextFactory:main: x509=X509@58e1d9d(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@446a1e84(file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/etc/keystore,file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/etc/keystore)
2017-08-16 16:55:17.944:INFO:oejus.SslContextFactory:main: x509=X509@4f0f2942(mykey,h=[],w=[]) for SslContextFactory@446a1e84(file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/etc/keystore,file:///tmp/jetty-distribution-9.4.7-SNAPSHOT/demo-base/etc/keystore)
2017-08-16 16:55:17.944:INFO:oejus.SslContextFactory:main: x509=X509@58e1d9d(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@446a1e84(file:///tmp/jetty-distribution-{VERSION}/demo-base/etc/keystore,file:///tmp/jetty-distribution-{VERSION}/demo-base/etc/keystore)
2017-08-16 16:55:17.944:INFO:oejus.SslContextFactory:main: x509=X509@4f0f2942(mykey,h=[],w=[]) for SslContextFactory@446a1e84(file:///tmp/jetty-distribution-{VERSION}/demo-base/etc/keystore,file:///tmp/jetty-distribution-{VERSION}/demo-base/etc/keystore)
2017-08-16 16:55:18.071:INFO:oejs.AbstractConnector:main: Started ServerConnector@41488b16{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
2017-08-16 16:55:18.072:INFO:oejs.Server:main: Started @3022ms
----
@ -179,7 +179,7 @@ INFO: Base directory was modified
2015-06-04 11:10:16.460:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/mybase/webapps/] at interval 1
2015-06-04 11:10:16.581:WARN::main: async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
2015-06-04 11:10:16.589:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2015-06-04 11:10:16.628:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1a407d53{/,[file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/WEB-INF/lib/example-async-rest-jar-9.3.0.v20150601.jar!/META-INF/resources],AVAILABLE}{/ROOT.war}
2015-06-04 11:10:16.628:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1a407d53{/,[file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/, jar:file:///tmp/jetty-0.0.0.0-8080-ROOT.war-_-any-4510228025526425427.dir/webapp/WEB-INF/lib/example-async-rest-jar-{VERSION}.jar!/META-INF/resources],AVAILABLE}{/ROOT.war}
2015-06-04 11:10:16.645:INFO:oejs.ServerConnector:main: Started ServerConnector@3abbfa04{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2015-06-04 11:10:16.646:INFO:oejs.Server:main: Started @634ms
----

View File

@ -499,6 +499,16 @@
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-conscrypt-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaspi</artifactId>

View File

@ -7,21 +7,26 @@ Installs the Conscrypt JSSE provider
[depend]
ssl
[provides]
alpn-impl
[files]
maven://org.conscrypt/conscrypt-openjdk-uber/${conscrypt.version}|lib/conscrypt/conscrypt-uber-${conscrypt.version}.jar
#maven://org.conscrypt/conscrypt-openjdk/${conscrypt.version}/jar/linux-x86_64|lib/conscrypt/conscrypt-${conscrypt.version}-linux-x86_64.jar
basehome:modules/conscrypt/conscrypt.xml|etc/conscrypt.xml
[lib]
lib/conscrypt/**.jar
[xml]
etc/conscrypt.xml
[lib]
lib/conscrypt/**.jar
lib/jetty-alpn-conscrypt-server-${jetty.version}.jar
[license]
Conscrypt is distributed under the Apache Licence 2.0
https://github.com/google/conscrypt/blob/master/LICENSE
[ini]
conscrypt.version?=1.0.0.RC9
jetty.sslContext.provider?=AndroidOpenSSL
conscrypt.version?=1.0.0.RC10
jetty.sslContext.provider?=Conscrypt

View File

@ -76,6 +76,7 @@ mov=video/quicktime
movie=video/x-sgi-movie
mp2=audio/mpeg
mp3=audio/mpeg
mp4=video/mp4
mpe=video/mpeg
mpeg=video/mpeg
mpg=video/mpeg

View File

@ -50,15 +50,15 @@
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.alpn</groupId>
<artifactId>alpn-api</artifactId>
<version>${alpn.api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<artifactId>jetty-alpn-openjdk8-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
@ -86,4 +86,21 @@
</dependency>
</dependencies>
<profiles>
<profile>
<id>jdk9</id>
<activation>
<jdk>[1.9,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-java-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -45,7 +45,7 @@ public abstract class NegotiatingClientConnection extends AbstractConnection
this.context = context;
}
protected SSLEngine getSSLEngine()
public SSLEngine getSSLEngine()
{
return engine;
}

View File

@ -18,35 +18,54 @@
package org.eclipse.jetty.io.ssl;
import java.util.List;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.Connection;
public interface ALPNProcessor
{
public interface Server
/**
* Initializes this ALPNProcessor
*
* @throws RuntimeException if this processor is unavailable (e.g. missing dependencies or wrong JVM)
*/
public default void init()
{
public static final ALPNProcessor.Server NOOP = new ALPNProcessor.Server()
{
};
public default void configure(SSLEngine sslEngine)
{
}
}
public interface Client
/**
* Tests if this processor can be applied to the given SSLEngine.
*
* @param sslEngine the SSLEngine to check
* @return true if the processor can be applied to the given SSLEngine
*/
public default boolean appliesTo(SSLEngine sslEngine)
{
public static final Client NOOP = new Client()
{
};
return false;
}
public default void configure(SSLEngine sslEngine, List<String> protocols)
{
}
/**
* Configures the given SSLEngine and the given Connection for ALPN.
*
* @param sslEngine the SSLEngine to configure
* @param connection the Connection to configure
* @throws RuntimeException if this processor cannot be configured
*/
public default void configure(SSLEngine sslEngine, Connection connection)
{
}
public default void process(SSLEngine sslEngine)
{
}
/**
* Server-side interface used by ServiceLoader.
*/
public interface Server extends ALPNProcessor
{
}
/**
* Client-side interface used by ServiceLoader.
*/
public interface Client extends ALPNProcessor
{
}
}

View File

@ -55,27 +55,27 @@ public abstract class NegotiatingServerConnection extends AbstractConnection
this.engine = engine;
}
protected List<String> getProtocols()
public List<String> getProtocols()
{
return protocols;
}
protected String getDefaultProtocol()
public String getDefaultProtocol()
{
return defaultProtocol;
}
protected Connector getConnector()
public Connector getConnector()
{
return connector;
}
protected SSLEngine getSSLEngine()
public SSLEngine getSSLEngine()
{
return engine;
}
protected String getProtocol()
public String getProtocol()
{
return protocol;
}

View File

@ -32,28 +32,6 @@ import org.eclipse.jetty.io.ssl.SslConnection;
public abstract class NegotiatingServerConnectionFactory extends AbstractConnectionFactory
{
public static void checkProtocolNegotiationAvailable()
{
try
{
String javaVersion = System.getProperty("java.version");
String alpnClassName = "org.eclipse.jetty.alpn.ALPN";
if (javaVersion.startsWith("1."))
{
Class<?> klass = ClassLoader.getSystemClassLoader().loadClass(alpnClassName);
if (klass.getClassLoader() != null)
throw new IllegalStateException(alpnClassName + " must be on JVM boot classpath");
}
else
{
NegotiatingServerConnectionFactory.class.getClassLoader().loadClass(alpnClassName);
}
}
catch (ClassNotFoundException x)
{
throw new IllegalStateException("No ALPN classes available");
}
}
private final List<String> negotiatedProtocols;
private String defaultProtocol;

View File

@ -109,7 +109,8 @@ public class ResourceHandler extends HandlerWrapper implements ResourceFactory,W
{
Context scontext = ContextHandler.getCurrentContext();
_context = (scontext == null?null:scontext.getContextHandler());
_mimeTypes = _context == null?new MimeTypes():_context.getMimeTypes();
if (_mimeTypes==null)
_mimeTypes = _context == null?new MimeTypes():_context.getMimeTypes();
_resourceService.setContentFactory(new ResourceContentFactory(this,_mimeTypes,_resourceService.getPrecompressedFormats()));
_resourceService.setWelcomeFactory(this);

View File

@ -44,6 +44,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@ -58,7 +59,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.CookieCompliance;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.LocalConnector.LocalEndPoint;
@ -151,6 +151,32 @@ public class RequestTest
assertTrue(responses.startsWith("HTTP/1.1 200"));
}
@Test
public void testParamExtraction_BadSequence() throws Exception
{
_handler._checker = new RequestTester()
{
@Override
public boolean check(HttpServletRequest request,HttpServletResponse response)
{
Map<String, String[]> map = request.getParameterMap();
// should have thrown a BadMessageException
return false;
}
};
//Send a request with query string with illegal hex code to cause
//an exception parsing the params
String request="GET /?test_%e0%x8%81=missing HTTP/1.1\r\n"+
"Host: whatever\r\n"+
"Content-Type: text/html;charset=utf8\n"+
"Connection: close\n"+
"\n";
String responses=_connector.getResponse(request);
assertThat("Responses", responses, startsWith("HTTP/1.1 400"));
}
@Test
public void testEmptyHeaders() throws Exception
{

View File

@ -0,0 +1,250 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.stream.Stream;
/**
* <p>Utility class to handle a Multi Release Jar file</p>
*/
public class MultiReleaseJarFile
{
private static final String META_INF_VERSIONS = "META-INF/versions/";
private final JarFile jarFile;
private final int majorVersion;
private final boolean multiRelease;
/* Map to hold unversioned name to VersionedJarEntry */
private final Map<String,VersionedJarEntry> entries;
/**
* Construct a multi release jar file for the current JVM version, ignoring directories.
* @param file The file to open
*/
public MultiReleaseJarFile(File file) throws IOException
{
this(file,JavaVersion.VERSION.getMajor(),false);
}
/**
* Construct a multi release jar file
* @param file The file to open
* @param majorVersion The major JVM version to apply when selecting a version.
* @param includeDirectories true if any directory entries should not be ignored
* @throws IOException if the jar file cannot be read
*/
public MultiReleaseJarFile(File file, int majorVersion, boolean includeDirectories) throws IOException
{
if (file==null || !file.exists() || !file.canRead() || file.isDirectory())
throw new IllegalArgumentException("bad jar file: "+file);
jarFile = new JarFile(file,true,JarFile.OPEN_READ);
this.majorVersion = majorVersion;
Manifest manifest = jarFile.getManifest();
if (manifest==null)
multiRelease = false;
else
multiRelease = Boolean.valueOf(String.valueOf(manifest.getMainAttributes().getValue("Multi-Release")));
Map<String,VersionedJarEntry> map = new TreeMap<>();
jarFile.stream()
.map(VersionedJarEntry::new)
.filter(e->(includeDirectories||!e.isDirectory()) && e.isApplicable())
.forEach(e->map.compute(e.name, (k, v) -> v==null || v.isReplacedBy(e) ? e : v));
for (Iterator<Map.Entry<String,VersionedJarEntry>> i = map.entrySet().iterator();i.hasNext();)
{
Map.Entry<String,VersionedJarEntry> e = i.next();
VersionedJarEntry entry = e.getValue();
if (entry.inner)
{
VersionedJarEntry outer = map.get(entry.outer);
if (entry.outer==null || outer.version!= entry.version)
i.remove();
}
}
entries = Collections.unmodifiableMap(map);
}
/**
* @return true IFF the jar is a multi release jar
*/
public boolean isMultiRelease()
{
return multiRelease;
}
/**
* @return The major version applied to this jar for the purposes of selecting entries
*/
public int getVersion()
{
return majorVersion;
}
/**
* @return A stream of versioned entries from the jar, excluded any that are not applicable
*/
public Stream<VersionedJarEntry> stream()
{
return entries.values().stream();
}
/** Get a versioned resource entry by name
* @param name The unversioned name of the resource
* @return The versioned entry of the resource
*/
public VersionedJarEntry getEntry(String name)
{
return entries.get(name);
}
@Override
public String toString()
{
return String.format("%s[%b,%d]",jarFile.getName(),isMultiRelease(),getVersion());
}
/**
* A versioned Jar entry
*/
public class VersionedJarEntry
{
final JarEntry entry;
final String name;
final int version;
final boolean inner;
final String outer;
VersionedJarEntry(JarEntry entry)
{
int v = 0;
String name = entry.getName();
if (name.startsWith(META_INF_VERSIONS))
{
v = -1;
int index = name.indexOf('/', META_INF_VERSIONS.length());
if (index > META_INF_VERSIONS.length() && index < name.length())
{
try
{
v = TypeUtil.parseInt(name, META_INF_VERSIONS.length(), index - META_INF_VERSIONS.length(), 10);
name = name.substring(index + 1);
}
catch (NumberFormatException x)
{
throw new RuntimeException("illegal version in "+jarFile,x);
}
}
}
this.entry = entry;
this.name = name;
this.version = v;
this.inner = name.contains("$") && name.toLowerCase().endsWith(".class");
this.outer = inner ? name.substring(0, name.indexOf('$')) + name.substring(name.length() - 6, name.length()) : null;
}
/**
* @return the unversioned name of the resource
*/
public String getName()
{
return name;
}
/**
* @return The name of the resource within the jar, which could be versioned
*/
public String getNameInJar()
{
return entry.getName();
}
/**
* @return The version of the resource or 0 for a base version
*/
public int getVersion()
{
return version;
}
/**
*
* @return True iff the entry is not from the base version
*/
public boolean isVersioned()
{
return version > 0;
}
/**
*
* @return True iff the entry is a directory
*/
public boolean isDirectory()
{
return entry.isDirectory();
}
/**
* @return An input stream of the content of the versioned entry.
* @throws IOException if something goes wrong!
*/
public InputStream getInputStream() throws IOException
{
return jarFile.getInputStream(entry);
}
boolean isApplicable()
{
if (multiRelease)
return this.version>=0 && this.version <= majorVersion && name.length()>0;
return this.version==0;
}
boolean isReplacedBy(VersionedJarEntry entry)
{
if (isDirectory())
return entry.version==0;
return this.name.equals(entry.name) && entry.version>version;
}
@Override
public String toString()
{
return String.format("%s->%s[%d]",name,entry.getName(),version);
}
}
}

View File

@ -0,0 +1,92 @@
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.io.File;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.jetty.toolchain.test.AdvancedRunner;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@RunWith(AdvancedRunner.class)
public class MultiReleaseJarFileTest
{
private File testResources = MavenTestingUtils.getTestResourcesDir().getAbsoluteFile();
private File example = new File(testResources,"example.jar");
@Test
public void testExampleJarIsMR() throws Exception
{
MultiReleaseJarFile jarFile = new MultiReleaseJarFile(example);
assertTrue(jarFile.isMultiRelease());
}
@Test
public void testBase() throws Exception
{
MultiReleaseJarFile jarFile = new MultiReleaseJarFile(example,8,false);
assertThat(jarFile.getEntry("META-INF/MANIFEST.MF").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/OnlyInBase.class").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/InBoth$InnerBase.class").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/InBoth$InnerBoth.class").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/InBoth.class").getVersion(), is(0));
assertThat(jarFile.stream().count(), is(5L));
}
@Test
public void test9() throws Exception
{
MultiReleaseJarFile jarFile = new MultiReleaseJarFile(example,9,false);
assertThat(jarFile.getEntry("META-INF/MANIFEST.MF").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/OnlyInBase.class").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/InBoth$InnerBoth.class").getVersion(), is(9));
assertThat(jarFile.getEntry("org/example/InBoth.class").getVersion(), is(9));
assertThat(jarFile.getEntry("org/example/OnlyIn9.class").getVersion(), is(9));
assertThat(jarFile.getEntry("org/example/onlyIn9/OnlyIn9.class").getVersion(), is(9));
assertThat(jarFile.getEntry("org/example/InBoth$Inner9.class").getVersion(), is(9));
assertThat(jarFile.stream().count(), is(7L));
}
@Test
public void test10() throws Exception
{
MultiReleaseJarFile jarFile = new MultiReleaseJarFile(example,10,false);
assertThat(jarFile.getEntry("META-INF/MANIFEST.MF").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/OnlyInBase.class").getVersion(), is(0));
assertThat(jarFile.getEntry("org/example/InBoth.class").getVersion(), is(10));
assertThat(jarFile.getEntry("org/example/OnlyIn9.class").getVersion(), is(9));
assertThat(jarFile.getEntry("org/example/onlyIn9/OnlyIn9.class").getVersion(), is(9));
assertThat(jarFile.getEntry("org/example/In10Only.class").getVersion(), is(10));
assertThat(jarFile.stream().count(), is(6L));
}
}

Binary file not shown.

View File

@ -43,7 +43,9 @@ import org.eclipse.jetty.util.resource.Resource;
* Subclasses should implement the processEntry(URL jarUrl, JarEntry entry)
* method to handle entries in jar files whose names match the supplied
* pattern.
* @deprecated Does not handle MR Jars
*/
@Deprecated()
public abstract class JarScanner extends org.eclipse.jetty.util.PatternMatcher
{
private static final Logger LOG = Log.getLogger(JarScanner.class);

View File

@ -21,6 +21,20 @@
<activation>
<jdk>[1.8,1.9)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-openjdk8-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
@ -116,12 +130,6 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>

View File

@ -71,9 +71,7 @@ detected.
<!-- disable cookies
<Get name="sessionHandler">
<Get name="sessionManager">
<Set name="usingCookies" type="boolean">false</Set>
</Get>
<Set name="usingCookies" type="boolean">false</Set>
</Get>
-->