Merged branch 'jetty-9.4.x' into 'jetty-9.4.x-4628-start-module-non-required'.
This commit is contained in:
commit
fda99cfd1e
|
@ -171,7 +171,7 @@
|
|||
<profile>
|
||||
<id>jdk9</id>
|
||||
<activation>
|
||||
<jdk>[1.9,)</jdk>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.9</source>
|
||||
<target>1.9</target>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
<release>9</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.9</source>
|
||||
<target>1.9</target>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
<release>9</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -46,11 +46,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>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-alpn-server</artifactId>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<groupId>org.eclipse.jetty.alpn</groupId>
|
||||
<artifactId>alpn-api</artifactId>
|
||||
<version>${alpn.api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
|
|
|
@ -18,13 +18,20 @@
|
|||
|
||||
package org.eclipse.jetty.alpn.openjdk8.client;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
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;
|
||||
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;
|
||||
|
@ -33,11 +40,31 @@ public class OpenJDK8ClientALPNProcessor implements ALPNProcessor.Client
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(OpenJDK8ClientALPNProcessor.class);
|
||||
|
||||
private Method alpnProtocols;
|
||||
private Method alpnProtocol;
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
if (JavaVersion.VERSION.getPlatform() != 8)
|
||||
throw new IllegalStateException(this + " not applicable for java " + JavaVersion.VERSION);
|
||||
|
||||
try
|
||||
{
|
||||
// JDK 8u252 has the JDK 9 ALPN API backported.
|
||||
// Use reflection so we can build with a JDK version less than 8u252.
|
||||
alpnProtocols = SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
|
||||
alpnProtocol = SSLEngine.class.getMethod("getApplicationProtocol");
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Using OpenJDK ALPN APIs instead of Jetty ALPN APIs");
|
||||
return;
|
||||
}
|
||||
catch (NoSuchMethodException x)
|
||||
{
|
||||
LOG.ignore(x);
|
||||
}
|
||||
|
||||
// Backported ALPN APIs not available.
|
||||
if (ALPN.class.getClassLoader() != null)
|
||||
throw new IllegalStateException(ALPN.class.getName() + " must be on JVM boot classpath");
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -53,14 +80,34 @@ public class OpenJDK8ClientALPNProcessor implements ALPNProcessor.Client
|
|||
@Override
|
||||
public void configure(SSLEngine sslEngine, Connection connection)
|
||||
{
|
||||
connection.addListener(new ALPNListener((ALPNClientConnection)connection));
|
||||
ALPNClientConnection alpnConnection = (ALPNClientConnection)connection;
|
||||
if (alpnProtocols == null)
|
||||
{
|
||||
connection.addListener(new ALPNConnectionListener(alpnConnection));
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Object protocols = alpnConnection.getProtocols().toArray(new String[0]);
|
||||
SSLParameters sslParameters = sslEngine.getSSLParameters();
|
||||
alpnProtocols.invoke(sslParameters, protocols);
|
||||
sslEngine.setSSLParameters(sslParameters);
|
||||
((SslConnection.DecryptedEndPoint)connection.getEndPoint()).getSslConnection()
|
||||
.addHandshakeListener(new ALPNSSLListener(alpnConnection));
|
||||
}
|
||||
catch (IllegalAccessException | InvocationTargetException x)
|
||||
{
|
||||
throw new IllegalStateException(this + " unable to set ALPN protocols", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class ALPNListener implements ALPN.ClientProvider, Connection.Listener
|
||||
private static final class ALPNConnectionListener implements ALPN.ClientProvider, Connection.Listener
|
||||
{
|
||||
private final ALPNClientConnection alpnConnection;
|
||||
|
||||
private ALPNListener(ALPNClientConnection connection)
|
||||
private ALPNConnectionListener(ALPNClientConnection connection)
|
||||
{
|
||||
alpnConnection = connection;
|
||||
}
|
||||
|
@ -102,4 +149,32 @@ public class OpenJDK8ClientALPNProcessor implements ALPNProcessor.Client
|
|||
alpnConnection.selected(protocol);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ALPNSSLListener implements SslHandshakeListener
|
||||
{
|
||||
private final ALPNClientConnection alpnConnection;
|
||||
|
||||
private ALPNSSLListener(ALPNClientConnection connection)
|
||||
{
|
||||
alpnConnection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handshakeSucceeded(Event event) throws SSLException
|
||||
{
|
||||
try
|
||||
{
|
||||
SSLEngine sslEngine = alpnConnection.getSSLEngine();
|
||||
String protocol = (String)alpnProtocol.invoke(sslEngine);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("selected protocol {}", protocol);
|
||||
alpnConnection.selected(protocol);
|
||||
}
|
||||
catch (IllegalAccessException | InvocationTargetException x)
|
||||
{
|
||||
SSLHandshakeException failure = new SSLHandshakeException(this + " unable to get ALPN protocol");
|
||||
throw (SSLHandshakeException)failure.initCause(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,19 @@
|
|||
|
||||
package org.eclipse.jetty.alpn.openjdk8.server;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
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;
|
||||
|
@ -35,11 +39,29 @@ public class OpenJDK8ServerALPNProcessor implements ALPNProcessor.Server
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(OpenJDK8ServerALPNProcessor.class);
|
||||
|
||||
private Method alpnSelector;
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
if (JavaVersion.VERSION.getPlatform() != 8)
|
||||
throw new IllegalStateException(this + " not applicable for java " + JavaVersion.VERSION);
|
||||
|
||||
try
|
||||
{
|
||||
// JDK 8u252 has the JDK 9 ALPN API backported.
|
||||
// Use reflection so we can build with a JDK version less than 8u252.
|
||||
alpnSelector = SSLEngine.class.getMethod("setHandshakeApplicationProtocolSelector", BiFunction.class);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Using OpenJDK ALPN APIs instead of Jetty ALPN APIs");
|
||||
return;
|
||||
}
|
||||
catch (NoSuchMethodException x)
|
||||
{
|
||||
LOG.ignore(x);
|
||||
}
|
||||
|
||||
// Backported ALPN APIs not available.
|
||||
if (ALPN.class.getClassLoader() != null)
|
||||
throw new IllegalStateException(ALPN.class.getName() + " must be on JVM boot classpath");
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -55,10 +77,26 @@ public class OpenJDK8ServerALPNProcessor implements ALPNProcessor.Server
|
|||
@Override
|
||||
public void configure(SSLEngine sslEngine, Connection connection)
|
||||
{
|
||||
connection.addListener(new ALPNListener((ALPNServerConnection)connection));
|
||||
if (alpnSelector == null)
|
||||
{
|
||||
ALPNListener listener = new ALPNListener((ALPNServerConnection)connection);
|
||||
connection.addListener(listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
ALPNCallback callback = new ALPNCallback((ALPNServerConnection)connection);
|
||||
alpnSelector.invoke(sslEngine, callback);
|
||||
}
|
||||
catch (IllegalAccessException | InvocationTargetException x)
|
||||
{
|
||||
throw new IllegalStateException(this + " unable to set ALPN selector", x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class ALPNListener implements ALPN.ServerProvider, Connection.Listener
|
||||
private static final class ALPNListener implements ALPN.ServerProvider, Connection.Listener
|
||||
{
|
||||
private final ALPNServerConnection alpnConnection;
|
||||
|
||||
|
@ -92,7 +130,7 @@ public class OpenJDK8ServerALPNProcessor implements ALPNProcessor.Server
|
|||
}
|
||||
|
||||
@Override
|
||||
public String select(List<String> protocols) throws SSLException
|
||||
public String select(List<String> protocols)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("select {} {}", alpnConnection, protocols);
|
||||
|
@ -100,4 +138,50 @@ public class OpenJDK8ServerALPNProcessor implements ALPNProcessor.Server
|
|||
return alpnConnection.getProtocol();
|
||||
}
|
||||
}
|
||||
|
||||
private static 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)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("apply {} {}", alpnConnection, protocols);
|
||||
alpnConnection.select(protocols);
|
||||
return alpnConnection.getProtocol();
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
// Cannot negotiate the protocol, return null to have
|
||||
// JSSE send Alert.NO_APPLICATION_PROTOCOL to the client.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handshakeSucceeded(Event event)
|
||||
{
|
||||
String protocol = alpnConnection.getProtocol();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("TLS handshake succeeded, protocol={} for {}", protocol, alpnConnection);
|
||||
if (protocol == null)
|
||||
alpnConnection.unsupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handshakeFailed(Event event, Throwable failure)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("TLS handshake failed " + alpnConnection, failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.10.v20161026|lib/alpn/alpn-boot-8.1.10.v20161026.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.10.v20161026.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.0.v20141016.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.2.v20141202.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.3.v20150130.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.4.v20150727|lib/alpn/alpn-boot-8.1.4.v20150727.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.4.v20150727.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.5.v20150921|lib/alpn/alpn-boot-8.1.5.v20150921.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.5.v20150921.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.6.v20151105|lib/alpn/alpn-boot-8.1.6.v20151105.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.6.v20151105.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.6.v20151105|lib/alpn/alpn-boot-8.1.6.v20151105.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.6.v20151105.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.7.v20160121|lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
|
|
@ -1,7 +0,0 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.8.v20160420|lib/alpn/alpn-boot-8.1.8.v20160420.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.8.v20160420.jar
|
|
@ -0,0 +1,4 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[depend]
|
||||
alpn-impl/alpn-11
|
|
@ -1,33 +1,22 @@
|
|||
DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
||||
|
||||
[description]
|
||||
Provides ALPN support for JDK 8, modifying the sun.security.ssl
|
||||
classes and adding them to the JVM boot classpath.
|
||||
This modification has a tight dependency on specific recent updates of
|
||||
Java 1.7 and Java 1.8 (Java versions prior to 1.7u40 are not supported).
|
||||
This module will use an appropriate alpn-boot jar for your
|
||||
specific version of Java.
|
||||
# IMPORTANT: Versions of Java that exist after this module was created are
|
||||
# not guaranteed to work with existing alpn-boot jars, and might
|
||||
# need a new alpn-boot to be created / tested / deployed by the
|
||||
# Jetty project in order to provide support for these future
|
||||
# Java versions.
|
||||
#
|
||||
# All versions of the alpn-boot jar can be found at
|
||||
# https://repo1.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/
|
||||
|
||||
[depend]
|
||||
alpn-impl/alpn-${java.version}
|
||||
|
||||
[lib]
|
||||
lib/jetty-alpn-openjdk8-server-${jetty.version}.jar
|
||||
Provides ALPN support for JDK 8, using the Jetty ALPN Agent.
|
||||
|
||||
[files]
|
||||
lib/
|
||||
lib/alpn/
|
||||
maven://org.mortbay.jetty.alpn/jetty-alpn-agent/2.0.10|lib/alpn/jetty-alpn-agent-2.0.10.jar
|
||||
|
||||
[lib]
|
||||
lib/jetty-alpn-openjdk8-server-${jetty.version}.jar
|
||||
|
||||
[license]
|
||||
ALPN is a hosted at github under the GPL v2 with ClassPath Exception.
|
||||
ALPN replaces/modifies OpenJDK classes in the sun.security.ssl package.
|
||||
The ALPN implementation for Java 8u242 and earlier replaces/modifies OpenJDK classes
|
||||
in the sun.security.ssl package.
|
||||
These modified classes are hosted at GitHub under the GPL v2 with ClassPath Exception.
|
||||
http://github.com/jetty-project/jetty-alpn
|
||||
http://openjdk.java.net/legal/gplv2+ce.html
|
||||
|
||||
[exec]
|
||||
-javaagent:lib/alpn/jetty-alpn-agent-2.0.10.jar
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<profile>
|
||||
<id>jdk9</id>
|
||||
<activation>
|
||||
<jdk>[1.9,)</jdk>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>jetty-alpn-java-client</module>
|
||||
|
|
|
@ -33,20 +33,21 @@ When using Jetty as a standalone server via the Jetty distribution, the `jetty-a
|
|||
|
||||
When using Jetty embedded, the `jetty-alpn-client` and `jetty-alpn-server` artifacts must be included in the classpath, respectively for client and server use cases.
|
||||
|
||||
The ALPN implementation is _provided_ to these two artifacts with the following three options:
|
||||
The ALPN implementation is _provided_ to these two artifacts with the following options:
|
||||
|
||||
* For JDK 8 only, a provider based on modified OpenJDK classes
|
||||
** Only works with JDK 8, pure Java implementation
|
||||
** Requires the `-Xbootclasspath/p` option on command line
|
||||
* For JDK 8 or later, a provider based on the link:#conscrypt[Conscrypt security provider]
|
||||
* For Java 8 only, a provider based on a pure Java implementation (no native code)
|
||||
** For Java 8 up to `1.8.0_242` included, this provider uses modified OpenJDK classes
|
||||
and requires the `-Xbootclasspath/p:` option on command line
|
||||
** For Java 8 from `1.8.0_252` included and later, this provider uses the standard OpenJDK
|
||||
ALPN APIs introduced in Java 9 (see below) that have been backported to `1.8.0_252` and
|
||||
does not require the `-Xbootclasspath/p:` option on command line
|
||||
* For Java 8 or later, a provider based on the link:#conscrypt[Conscrypt security provider]
|
||||
** Works with JDK 8 or later and provides improved performance
|
||||
** Binds to the OpenSSL native library shipped by Conscrypt and is therefore only available on the platforms supported by Conscrypt
|
||||
* For JDK 9 or later, a provider based on the ALPN APIs present in the JDK
|
||||
** Works with JDK 9 or later, pure Java implementation
|
||||
* For Java 9 or later, a provider based on the standard OpenJDK ALPN APIs
|
||||
** Works with JDK 9 or later, pure Java implementation (no native code)
|
||||
** Lower performance than Conscrypt
|
||||
|
||||
The first, although hosted under the umbrella of the Jetty project, is independent of Jetty (the Servlet Container); you can use it in any other Java network server.
|
||||
|
||||
Each provider above provides an ALPN _service_ implementation; Jetty uses the `ServiceLoader` mechanism to load these service implementations.
|
||||
At least one valid provider must be present in the server classpath.
|
||||
For example, using JDK 8 with the JDK 9 ALPN provider is an _invalid_ combination.
|
||||
|
@ -60,7 +61,18 @@ It is therefore possible to have multiple providers active at the same time, for
|
|||
[[alpn-openjdk8]]
|
||||
==== ALPN and OpenJDK 8
|
||||
|
||||
When using JDKs based on OpenJDK 8 (for JDK 9 see link:#alpn-jdk9[above]), and you do not or cannot use link:#conscrypt[Conscrypt], you can use Jetty's ALPN boot library to provide the ALPN service implementation, via the `alpn-boot` artifact.
|
||||
When using JDKs based on OpenJDK 8 (for JDK 9 see link:#alpn-jdk9[here]), and you do not or
|
||||
cannot use link:#conscrypt[Conscrypt], the ALPN implementation is provided by the
|
||||
`jetty-alpn-openjdk8-client` or `jetty-alpn-openjdk8-server` artifacts.
|
||||
|
||||
For Java 8 versions up to `1.8.0_242` included, you also need the Jetty's ALPN boot library
|
||||
to provide the ALPN service implementation, via the `alpn-boot` artifact.
|
||||
For Java 8 versions from `1.8.0_252` included and later, Jetty's ALPN boot library is not
|
||||
necessary because the OpenJDK ALPN APIs have been backported to `1.8.0_252` and the
|
||||
`jetty-alpn-openjdk8-*` artifacts can use these backported APIs if their presence is detected.
|
||||
|
||||
Alternatively, you can use the link:#alpn-openjdk8-agent[Jetty ALPN agent], that in turn uses
|
||||
theJetty ALPN boot library to transform the relevant OpenJDK classes when they are loaded.
|
||||
|
||||
The Jetty ALPN boot library modifies the relevant OpenJDK classes to add ALPN support and provides an ALPN API that application can use to enable ALPN.
|
||||
|
||||
|
@ -69,13 +81,14 @@ This enables transitively the `alpn-8` module which puts the `jetty-alpn-openjdk
|
|||
|
||||
When using Jetty embedded, the ALPN support is provided by the `jetty-alpn-openjdk8-client` and `jetty-alpn-openjdk8-server` artifacts, respectively for client usage and server usage.
|
||||
|
||||
To get ALPN working with the Jetty ALPN Boot library, you need:
|
||||
To get ALPN working with Java 8, you must have the `jetty-alpn-openjdk8-client` artifact or
|
||||
the `jetty-alpn-openjdk8-server` artifact in the classpath.
|
||||
|
||||
* to start the JVM with the Jetty ALPN Boot library in the boot classpath
|
||||
* to have the `jetty-alpn-openjdk8-client` artifact or the `jetty-alpn-openjdk8-server`
|
||||
artifact in the classpath
|
||||
Additionally, if you are using OpenJDK `1.8.0_242` or earlier, you need the Jetty ALPN boot
|
||||
library (corresponding to the exact OpenJDK version you are using) in the boot classpath,
|
||||
or alternatively you need the link:#alpn-openjdk8-agent[Jetty ALPN agent].
|
||||
|
||||
Start the JVM as follows:
|
||||
In the case of the Jetty ALPN boot library, start the JVM as follows:
|
||||
|
||||
[source, plain, subs="{sub-order}"]
|
||||
----
|
||||
|
@ -84,7 +97,45 @@ java -Xbootclasspath/p:<path_to_alpn_boot_jar> ...
|
|||
|
||||
Where `path_to_alpn_boot_jar` is the path on the file system for the `alpn-boot` artifact, such as the one at the Maven coordinates `org.mortbay.jetty.alpn:alpn-boot`.
|
||||
|
||||
Be certain to get the link:#alpn-versions[ALPN boot artifact version that matches the version of your JRE].
|
||||
____
|
||||
[IMPORTANT]
|
||||
Be certain to get the
|
||||
link:#alpn-versions[ALPN boot artifact version that matches the version of your JRE].
|
||||
____
|
||||
|
||||
[[alpn-openjdk8-agent]]
|
||||
==== ALPN agent and OpenJDK 8
|
||||
|
||||
The Jetty Project also maintains the
|
||||
https://github.com/jetty-project/jetty-alpn-agent[Jetty ALPN agent], which is a JVM
|
||||
agent that provides the ALPN implementation.
|
||||
The Jetty ALPN agent can be use in alternative (never together) with the
|
||||
link:#alpn-openjdk8[ALPN boot library].
|
||||
|
||||
The Jetty ALPN agent contains the ALPN boot libraries for every JDK 8 version.
|
||||
The agent can be used only with Java 8, but works with _any_ Java 8 version.
|
||||
|
||||
The Jetty ALPN agent detects the JDK version currently running, picks the correspondent
|
||||
ALPN boot library (or picks none if the JDK version is `1.8.0_252` or later), and
|
||||
transforms, if necessary, the relevant OpenJDK classes to provide the ALPN support.
|
||||
|
||||
To use the Jetty ALPN agent, start the JVM as follows:
|
||||
|
||||
[source, plain, subs="{sub-order}"]
|
||||
----
|
||||
java -javaagent:<path_to_alpn_agent_jar> ...
|
||||
----
|
||||
|
||||
____
|
||||
[NOTE]
|
||||
The Jetty ALPN agent works with any Java 8 version. It is _required_ if you use
|
||||
an OpenJDK version up to `1.8.0_242` included, and it is _optional_ if you use an
|
||||
OpenJDK version equal or greater than `1.8.0_252`.
|
||||
|
||||
The Jetty ALPN agent can be left on the command line even when using an OpenJDK version
|
||||
equal or greater than `1.8.0_252` but we recommend to remove it from the command line
|
||||
when you use OpenJDK `1.8.0_252` or later.
|
||||
____
|
||||
|
||||
[[alpn-conscrypt]]
|
||||
==== ALPN and Conscrypt
|
||||
|
@ -359,6 +410,7 @@ The ALPN implementation, relying on modifications of OpenJDK classes, updates ev
|
|||
|1.8.0u232 |8.1.13.v20181017
|
||||
|1.8.0u241^[1]^ |8.1.13.v20181017
|
||||
|1.8.0u242 |8.1.13.v20181017
|
||||
|1.8.0u252 and later | NOT NECESSARY
|
||||
|=============================
|
||||
^[1]^ These are Oracle releases for which the source code is not available,
|
||||
or it is unclear what exactly is because there is no correspondent tag in
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Configure a factory for HazelcastSessionDataStore using -->
|
||||
<!-- an embedded Hazelcast Instance -->
|
||||
<!-- an remote Hazelcast Instance -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
|
@ -15,6 +15,7 @@
|
|||
<Set name="gracePeriodSec"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
<Set name="savePeriodSec"><Property name="jetty.session.savePeriod.seconds" default="0" /></Set>
|
||||
<Set name="onlyClient"><Property name="jetty.session.hazelcast.onlyClient" default="true" /></Set>
|
||||
<Set name="addresses"><Property name="jetty.session.hazelcast.addresses" default="" /></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -13,7 +13,7 @@ session-store
|
|||
sessions
|
||||
|
||||
[files]
|
||||
maven://com.hazelcast/hazelcast/3.9.4|lib/hazelcast/hazelcast-3.9.4.jar
|
||||
maven://com.hazelcast/hazelcast/3.12.6|lib/hazelcast/hazelcast-3.12.6.jar
|
||||
|
||||
[xml]
|
||||
etc/sessions/hazelcast/default.xml
|
||||
|
@ -31,7 +31,6 @@ http://www.apache.org/licenses/LICENSE-2.0.html
|
|||
[ini-template]
|
||||
jetty.session.hazelcast.mapName=jetty-distributed-session-map
|
||||
jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE
|
||||
#jetty.session.hazelcast.configurationLocation=
|
||||
jetty.session.hazelcast.scavengeZombies=false
|
||||
jetty.session.gracePeriod.seconds=3600
|
||||
jetty.session.savePeriod.seconds=0
|
||||
|
|
|
@ -13,8 +13,8 @@ session-store
|
|||
sessions
|
||||
|
||||
[files]
|
||||
maven://com.hazelcast/hazelcast/3.9.4|lib/hazelcast/hazelcast-3.9.4.jar
|
||||
maven://com.hazelcast/hazelcast-client/3.9.4|lib/hazelcast/hazelcast-client-3.9.4.jar
|
||||
maven://com.hazelcast/hazelcast/3.12.6|lib/hazelcast/hazelcast-3.12.6.jar
|
||||
maven://com.hazelcast/hazelcast-client/3.12.6|lib/hazelcast/hazelcast-client-3.12.6.jar
|
||||
|
||||
[xml]
|
||||
etc/sessions/hazelcast/remote.xml
|
||||
|
@ -34,6 +34,6 @@ jetty.session.hazelcast.mapName=jetty-distributed-session-map
|
|||
jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE
|
||||
jetty.session.hazelcast.onlyClient=true
|
||||
jetty.session.hazelcast.scavengeZombies=false
|
||||
#jetty.session.hazelcast.configurationLocation=
|
||||
jetty.session.gracePeriod.seconds=3600
|
||||
jetty.session.savePeriod.seconds=0
|
||||
#jetty.session.hazelcast.addresses=
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.hazelcast.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.hazelcast.client.HazelcastClient;
|
||||
import com.hazelcast.client.config.ClientConfig;
|
||||
|
@ -29,6 +30,7 @@ import com.hazelcast.config.SerializerConfig;
|
|||
import com.hazelcast.config.XmlConfigBuilder;
|
||||
import com.hazelcast.core.Hazelcast;
|
||||
import com.hazelcast.core.HazelcastInstance;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.server.session.SessionDataStore;
|
||||
|
@ -57,6 +59,8 @@ public class HazelcastSessionDataStoreFactory
|
|||
|
||||
private boolean scavengeZombies = false;
|
||||
|
||||
private String addresses;
|
||||
|
||||
public boolean isScavengeZombies()
|
||||
{
|
||||
return scavengeZombies;
|
||||
|
@ -81,6 +85,12 @@ public class HazelcastSessionDataStoreFactory
|
|||
if (configurationLocation == null)
|
||||
{
|
||||
ClientConfig config = new ClientConfig();
|
||||
|
||||
if (addresses != null && !addresses.isEmpty())
|
||||
{
|
||||
config.getNetworkConfig().setAddresses(Arrays.asList(addresses.split(",")));
|
||||
}
|
||||
|
||||
SerializerConfig sc = new SerializerConfig()
|
||||
.setImplementation(new SessionDataSerializer())
|
||||
.setTypeClass(SessionData.class);
|
||||
|
@ -201,4 +211,14 @@ public class HazelcastSessionDataStoreFactory
|
|||
{
|
||||
this.hazelcastInstanceName = hazelcastInstanceName;
|
||||
}
|
||||
|
||||
public String getAddresses()
|
||||
{
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public void setAddresses(String addresses)
|
||||
{
|
||||
this.addresses = addresses;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -774,7 +774,7 @@
|
|||
<profile>
|
||||
<id>jdk9</id>
|
||||
<activation>
|
||||
<jdk>[1.9,)</jdk>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<profile>
|
||||
<id>jdk9</id>
|
||||
<activation>
|
||||
<jdk>[1.9,)</jdk>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
|
@ -23,6 +23,8 @@ import java.io.ByteArrayOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -33,6 +35,8 @@ import javax.servlet.http.Part;
|
|||
|
||||
import org.eclipse.jetty.http.MultiPartFormInputStream.MultiPart;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -885,6 +889,97 @@ public class MultiPartFormInputStreamTest
|
|||
assertEquals("the end", baos.toString("US-ASCII"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFragmentation() throws IOException
|
||||
{
|
||||
String contentType = "multipart/form-data, boundary=----WebKitFormBoundaryhXfFAMfUnUKhmqT8";
|
||||
String payload1 =
|
||||
"------WebKitFormBoundaryhXfFAMfUnUKhmqT8\r\n" +
|
||||
"Content-Disposition: form-data; name=\"field1\"\r\n\r\n" +
|
||||
"value1" +
|
||||
"\r\n--";
|
||||
String payload2 = "----WebKitFormBoundaryhXfFAMfUnUKhmqT8\r\n" +
|
||||
"Content-Disposition: form-data; name=\"field2\"\r\n\r\n" +
|
||||
"value2" +
|
||||
"\r\n------WebKitFormBoundaryhXfFAMfUnUKhmqT8--\r\n";
|
||||
|
||||
// Split the content into separate reads, with the content broken up on the boundary string.
|
||||
AppendableInputStream stream = new AppendableInputStream();
|
||||
stream.append(payload1);
|
||||
stream.append("");
|
||||
stream.append(payload2);
|
||||
stream.endOfContent();
|
||||
|
||||
MultipartConfigElement config = new MultipartConfigElement(_dirname);
|
||||
MultiPartFormInputStream mpis = new MultiPartFormInputStream(stream, contentType, config, _tmpDir);
|
||||
mpis.setDeleteOnExit(true);
|
||||
|
||||
// Check size.
|
||||
Collection<Part> parts = mpis.getParts();
|
||||
assertThat(parts.size(), is(2));
|
||||
|
||||
// Check part content.
|
||||
assertThat(IO.toString(mpis.getPart("field1").getInputStream()), is("value1"));
|
||||
assertThat(IO.toString(mpis.getPart("field2").getInputStream()), is("value2"));
|
||||
}
|
||||
|
||||
static class AppendableInputStream extends InputStream
|
||||
{
|
||||
private static final ByteBuffer EOF = ByteBuffer.allocate(0);
|
||||
private final BlockingArrayQueue<ByteBuffer> buffers = new BlockingArrayQueue<>();
|
||||
private ByteBuffer current;
|
||||
|
||||
public void append(String data)
|
||||
{
|
||||
append(data.getBytes(StandardCharsets.US_ASCII));
|
||||
}
|
||||
|
||||
public void append(byte[] data)
|
||||
{
|
||||
buffers.add(BufferUtil.toBuffer(data));
|
||||
}
|
||||
|
||||
public void endOfContent()
|
||||
{
|
||||
buffers.add(EOF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException
|
||||
{
|
||||
byte[] buf = new byte[1];
|
||||
while (true)
|
||||
{
|
||||
int len = read(buf, 0, 1);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
if (len > 0)
|
||||
return buf[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
if (current == null)
|
||||
current = buffers.poll();
|
||||
if (current == EOF)
|
||||
return -1;
|
||||
if (BufferUtil.isEmpty(current))
|
||||
{
|
||||
current = null;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.wrap(b, off, len);
|
||||
buffer.flip();
|
||||
int read = BufferUtil.append(buffer, current);
|
||||
if (BufferUtil.isEmpty(current))
|
||||
current = buffers.poll();
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuotedPrintableEncoding() throws Exception
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
<id>copy-alpn-agent</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
|
@ -29,8 +29,8 @@
|
|||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.mortbay.jetty.alpn</groupId>
|
||||
<artifactId>alpn-boot</artifactId>
|
||||
<version>${alpn.version}</version>
|
||||
<artifactId>jetty-alpn-agent</artifactId>
|
||||
<version>${alpn.agent.version}</version>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/alpn</outputDirectory>
|
||||
|
@ -43,7 +43,7 @@
|
|||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
|
||||
<argLine>-javaagent:${project.build.directory}/alpn/jetty-alpn-agent-${alpn.agent.version}.jar=debug=true</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -54,12 +54,6 @@
|
|||
<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-openjdk8-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -68,6 +62,18 @@
|
|||
<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</groupId>
|
||||
<artifactId>jetty-alpn-openjdk8-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>http2-server</artifactId>
|
||||
|
@ -81,21 +87,4 @@
|
|||
</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>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<profile>
|
||||
<id>jdk8</id>
|
||||
<activation>
|
||||
<jdk>[1.8,1.9)</jdk>
|
||||
<jdk>[1.8,9)</jdk>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
<id>copy-alpn-agent</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
|
@ -35,8 +35,8 @@
|
|||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.mortbay.jetty.alpn</groupId>
|
||||
<artifactId>alpn-boot</artifactId>
|
||||
<version>${alpn.version}</version>
|
||||
<artifactId>jetty-alpn-agent</artifactId>
|
||||
<version>${alpn.agent.version}</version>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/alpn</outputDirectory>
|
||||
|
@ -49,16 +49,29 @@
|
|||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
|
||||
<argLine>-javaagent:${project.build.directory}/alpn/jetty-alpn-agent-${alpn.agent.version}.jar=debug=true</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</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</groupId>
|
||||
<artifactId>jetty-alpn-openjdk8-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>jdk9</id>
|
||||
<activation>
|
||||
<jdk>[1.9,)</jdk>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
<profile>
|
||||
<id>jdk8</id>
|
||||
<activation>
|
||||
<jdk>[1.8,1.9)</jdk>
|
||||
<jdk>[1.8,9)</jdk>
|
||||
</activation>
|
||||
<modules>
|
||||
<!-- These tests can only be run in Java 8 -->
|
||||
<module>http2-alpn-tests</module>
|
||||
</modules>
|
||||
</profile>
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
<profile>
|
||||
<id>jdk9+</id>
|
||||
<activation>
|
||||
<jdk>[1.9,)</jdk>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
<exam.version>4.13.1</exam.version>
|
||||
<url.version>2.6.1</url.version>
|
||||
<injection.bundle.version>1.0</injection.bundle.version>
|
||||
<skipTests>true</skipTests>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!-- Pax Exam Dependencies -->
|
||||
|
@ -446,7 +445,6 @@
|
|||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipTests>${skipTests}</skipTests>
|
||||
<systemPropertyVariables>
|
||||
<mavenRepoPath>${settings.localRepository}</mavenRepoPath>
|
||||
<settingsFilePath>${env.GLOBAL_MVN_SETTINGS}</settingsFilePath>
|
||||
|
@ -541,20 +539,17 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<skipTests>false</skipTests>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- No point defining -javaagent as the actual OSGi VM is run as a forked process by pax-exam -->
|
||||
<!-- But we do pass the sys property of the jetty-alpn-agent jar so that it can be configured inside tests -->
|
||||
<argLine>-Dmortbay-alpn-agent=${settings.localRepository}/org/mortbay/jetty/alpn/jetty-alpn-agent/${alpn.agent.version}/jetty-alpn-agent-${alpn.agent.version}.jar -Dconscrypt-version=${conscrypt.version}</argLine>
|
||||
<excludes>
|
||||
<exclude>**/TestJettyOSGiBootHTTP2JDK9*</exclude>
|
||||
</excludes>
|
||||
<!-- No point defining -Xbootclasspath as the actual OSGi VM is run as a forked process by pax-exam -->
|
||||
<!-- But we do pass the sys property of the alpn-boot jar so that it can be configured inside tests -->
|
||||
<argLine>-Dmortbay-alpn-boot=${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar -Dconscrypt-version=${conscrypt.version}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -591,15 +586,11 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<skipTests>false</skipTests>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipTests>${skipTests}</skipTests>
|
||||
<excludes>
|
||||
<exclude>**/TestJettyOSGiBootHTTP2</exclude>
|
||||
</excludes>
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.osgi.framework.ServiceReference;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
|
||||
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
|
||||
|
@ -93,18 +92,13 @@ public class TestJettyOSGiBootHTTP2
|
|||
List<Option> res = new ArrayList<>();
|
||||
res.add(CoreOptions.systemProperty("jetty.alpn.protocols").value("h2,http/1.1"));
|
||||
|
||||
String alpnBoot = System.getProperty("mortbay-alpn-boot");
|
||||
if (alpnBoot == null)
|
||||
{
|
||||
throw new IllegalStateException("Define path to alpn boot jar as system property -Dmortbay-alpn-boot");
|
||||
}
|
||||
File checkALPNBoot = new File(alpnBoot);
|
||||
if (!checkALPNBoot.exists())
|
||||
{
|
||||
throw new IllegalStateException("Unable to find the alpn boot jar here: " + alpnBoot);
|
||||
}
|
||||
|
||||
res.add(CoreOptions.vmOptions("-Xbootclasspath/p:" + checkALPNBoot.getAbsolutePath()));
|
||||
String alpnAgent = System.getProperty("mortbay-alpn-agent");
|
||||
if (alpnAgent == null)
|
||||
throw new IllegalStateException("Define path to alpn agent jar as system property -Dmortbay-alpn-agent");
|
||||
File alpnAgentFile = new File(alpnAgent);
|
||||
if (!alpnAgentFile.exists())
|
||||
throw new IllegalStateException("Unable to find the alpn agent jar here: " + alpnAgent);
|
||||
res.add(CoreOptions.vmOptions("-javaagent:" + alpnAgentFile.getAbsolutePath() + "=debug=true"));
|
||||
|
||||
res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("jetty-osgi-alpn").versionAsInProject().noStart());
|
||||
res.add(mavenBundle().groupId("org.eclipse.jetty").artifactId("jetty-alpn-openjdk8-server").versionAsInProject().start());
|
||||
|
@ -116,20 +110,13 @@ public class TestJettyOSGiBootHTTP2
|
|||
return res;
|
||||
}
|
||||
|
||||
public void checkALPNBootOnBootstrapClasspath() throws Exception
|
||||
{
|
||||
Class<?> alpn = Thread.currentThread().getContextClassLoader().loadClass("org.eclipse.jetty.alpn.ALPN");
|
||||
assertNotNull(alpn);
|
||||
assertNull(alpn.getClassLoader());
|
||||
}
|
||||
|
||||
public void assertAllBundlesActiveOrResolved()
|
||||
{
|
||||
TestOSGiUtil.debugBundles(bundleContext);
|
||||
TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
|
||||
Bundle openjdk8 = TestOSGiUtil.getBundle(bundleContext, "org.eclipse.jetty.alpn.openjdk8.server");
|
||||
assertNotNull(openjdk8);
|
||||
ServiceReference[] services = openjdk8.getRegisteredServices();
|
||||
ServiceReference<?>[] services = openjdk8.getRegisteredServices();
|
||||
assertNotNull(services);
|
||||
Bundle server = TestOSGiUtil.getBundle(bundleContext, "org.eclipse.jetty.alpn.server");
|
||||
assertNotNull(server);
|
||||
|
@ -139,10 +126,7 @@ public class TestJettyOSGiBootHTTP2
|
|||
public void testHTTP2() throws Exception
|
||||
{
|
||||
if (Boolean.getBoolean(TestOSGiUtil.BUNDLE_DEBUG))
|
||||
{
|
||||
checkALPNBootOnBootstrapClasspath();
|
||||
assertAllBundlesActiveOrResolved();
|
||||
}
|
||||
|
||||
HttpClient httpClient = null;
|
||||
HTTP2Client http2Client = null;
|
||||
|
@ -151,7 +135,7 @@ public class TestJettyOSGiBootHTTP2
|
|||
//get the port chosen for https
|
||||
String tmp = System.getProperty("boot.https.port");
|
||||
assertNotNull(tmp);
|
||||
int port = Integer.valueOf(tmp.trim());
|
||||
int port = Integer.parseInt(tmp.trim());
|
||||
|
||||
Path path = Paths.get("src", "test", "config");
|
||||
File keys = path.resolve("etc").resolve("keystore").toFile();
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
package org.eclipse.jetty.plus.webapp;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
|
@ -35,6 +38,7 @@ import org.eclipse.jetty.plus.jndi.EnvEntry;
|
|||
import org.eclipse.jetty.plus.jndi.Link;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -121,14 +125,6 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
String type = node.getString("env-entry-type", false, true);
|
||||
String valueStr = node.getString("env-entry-value", false, true);
|
||||
|
||||
//if there's no value there's no point in making a jndi entry
|
||||
//nor processing injection entries
|
||||
if (valueStr == null || valueStr.equals(""))
|
||||
{
|
||||
LOG.warn("No value for env-entry-name " + name);
|
||||
return;
|
||||
}
|
||||
|
||||
Origin o = context.getMetaData().getOrigin("env-entry." + name);
|
||||
switch (o)
|
||||
{
|
||||
|
@ -136,14 +132,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
{
|
||||
//no descriptor has configured an env-entry of this name previously
|
||||
context.getMetaData().setOrigin("env-entry." + name, descriptor);
|
||||
//the javaee_5.xsd says that the env-entry-type is optional
|
||||
//if there is an <injection> element, because you can get
|
||||
//type from the element, but what to do if there is more
|
||||
//than one <injection> element, do you just pick the type
|
||||
//of the first one?
|
||||
addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
|
||||
Object value = TypeUtil.valueOf(type, valueStr);
|
||||
bindEnvEntry(name, value);
|
||||
makeEnvEntryInjectionsAndBindings(context, descriptor, node, name, type, valueStr);
|
||||
break;
|
||||
}
|
||||
case WebXml:
|
||||
|
@ -158,9 +147,7 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
//We're processing web-defaults, web.xml or web-override. Any of them can
|
||||
//set or change the env-entry.
|
||||
context.getMetaData().setOrigin("env-entry." + name, descriptor);
|
||||
addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
|
||||
Object value = TypeUtil.valueOf(type, valueStr);
|
||||
bindEnvEntry(name, value);
|
||||
makeEnvEntryInjectionsAndBindings(context, descriptor, node, name, type, valueStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -705,6 +692,9 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
*/
|
||||
public void addInjections(WebAppContext context, Descriptor descriptor, XmlParser.Node node, String jndiName, Class<?> valueClass)
|
||||
{
|
||||
Objects.requireNonNull(context);
|
||||
Objects.requireNonNull(node);
|
||||
|
||||
Iterator<XmlParser.Node> itor = node.iterator("injection-target");
|
||||
|
||||
while (itor.hasNext())
|
||||
|
@ -755,31 +745,59 @@ public class PlusDescriptorProcessor extends IterativeDescriptorProcessor
|
|||
*/
|
||||
public void bindEnvEntry(String name, Object value) throws Exception
|
||||
{
|
||||
InitialContext ic = null;
|
||||
boolean bound = false;
|
||||
//check to see if we bound a value and an EnvEntry with this name already
|
||||
//when we processed the server and the webapp's naming environment
|
||||
//@see EnvConfiguration.bindEnvEntries()
|
||||
ic = new InitialContext();
|
||||
InitialContext ic = new InitialContext();
|
||||
Context envCtx = (Context)ic.lookup("java:comp/env");
|
||||
NamingUtil.bind(envCtx, name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make injections and any java:comp/env bindings necessary given an env-entry declaration.
|
||||
* The handling of env-entries is different to other resource declarations like resource-ref, resource-env-ref etc
|
||||
* because we allow the EnvEntry (@see org.eclipse.jetty.plus.jndi.EnvEntry) class that is configured externally to the webapp
|
||||
* to specify a value that can override a value present in a web.xml descriptor.
|
||||
*
|
||||
* @param context the WebAppContext of the env-entry
|
||||
* @param descriptor the web.xml, web-default.xml, web-override.xml or web-fragment.xml
|
||||
* @param node the parsed xml representation of the env-entry declaration
|
||||
* @param name the name field of the env-entry
|
||||
* @param type the type field of the env-entry
|
||||
* @param value the value field of the env-entry
|
||||
* @throws Exception
|
||||
*/
|
||||
public void makeEnvEntryInjectionsAndBindings(WebAppContext context, Descriptor descriptor, XmlParser.Node node, String name, String type, String value) throws Exception
|
||||
{
|
||||
InitialContext ic = new InitialContext();
|
||||
try
|
||||
{
|
||||
NamingEntry ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntryUtil.makeNamingEntryName(ic.getNameParser(""), name));
|
||||
if (ne != null && ne instanceof EnvEntry)
|
||||
EnvEntry envEntry = (EnvEntry)ic.lookup("java:comp/env/" + NamingEntryUtil.makeNamingEntryName(ic.getNameParser(""), name));
|
||||
|
||||
if (StringUtil.isEmpty(value))
|
||||
{
|
||||
EnvEntry ee = (EnvEntry)ne;
|
||||
bound = ee.isOverrideWebXml();
|
||||
//There is an empty or missing value in the env-entry:
|
||||
//If there is an existing EnvEntry (eg from a declaration in jetty-env.xml) that is override=true, then
|
||||
//we make the injection, but we can skip the rebinding becase we want to use the value already bound.
|
||||
//If there isn't an existing EnvEntry then there is nothing to do: according to the spec we do not make
|
||||
//an injection if the env-entry value is missing, and of course there is no value to rebind.
|
||||
if (envEntry != null && envEntry.isOverrideWebXml())
|
||||
addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
|
||||
}
|
||||
else
|
||||
{
|
||||
//There is a value for the env-entry:
|
||||
//According to the spec, we need to make an injection (if one is present).
|
||||
//If there is an existing EnvEntry(eg from a declaration in jetty-env.xml) that is override=false, then
|
||||
//we need to rebind name with the value from web.xml.
|
||||
addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
|
||||
|
||||
if (envEntry == null || !envEntry.isOverrideWebXml())
|
||||
bindEnvEntry(name, TypeUtil.valueOf(type, value));
|
||||
}
|
||||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
bound = false;
|
||||
}
|
||||
|
||||
if (!bound)
|
||||
{
|
||||
//either nothing was bound or the value from web.xml should override
|
||||
Context envCtx = (Context)ic.lookup("java:comp/env");
|
||||
NamingUtil.bind(envCtx, name, value);
|
||||
//No matching EnvEntry has previously been bound so make the injection and do the binding with the value from web.xml
|
||||
addInjections(context, descriptor, node, name, TypeUtil.fromName(type));
|
||||
bindEnvEntry(name, TypeUtil.valueOf(type, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,14 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.net.URL;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.plus.annotation.Injection;
|
||||
import org.eclipse.jetty.plus.annotation.InjectionCollection;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.util.IntrospectionUtil;
|
||||
import org.eclipse.jetty.webapp.Descriptor;
|
||||
import org.eclipse.jetty.webapp.FragmentDescriptor;
|
||||
import org.eclipse.jetty.webapp.Origin;
|
||||
|
@ -39,6 +46,7 @@ import static org.hamcrest.Matchers.is;
|
|||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
@ -48,6 +56,7 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
*/
|
||||
public class PlusDescriptorProcessorTest
|
||||
{
|
||||
protected static final Class<?>[] STRING_ARG = new Class[]{String.class};
|
||||
protected WebDescriptor webDescriptor;
|
||||
protected FragmentDescriptor fragDescriptor1;
|
||||
protected FragmentDescriptor fragDescriptor2;
|
||||
|
@ -55,19 +64,95 @@ public class PlusDescriptorProcessorTest
|
|||
protected FragmentDescriptor fragDescriptor4;
|
||||
protected WebAppContext context;
|
||||
|
||||
public static class TestInjections
|
||||
{
|
||||
private String foo;
|
||||
private String bah;
|
||||
private String empty;
|
||||
private String vacuum;
|
||||
private String webXmlOnly;
|
||||
|
||||
public String getWebXmlOnly()
|
||||
{
|
||||
return webXmlOnly;
|
||||
}
|
||||
|
||||
public void setWebXmlOnly(String webXmlOnly)
|
||||
{
|
||||
this.webXmlOnly = webXmlOnly;
|
||||
}
|
||||
|
||||
public String getVacuum()
|
||||
{
|
||||
return vacuum;
|
||||
}
|
||||
|
||||
public void setVacuum(String val)
|
||||
{
|
||||
vacuum = val;
|
||||
}
|
||||
|
||||
public String getEmpty()
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
|
||||
public void setEmpty(String val)
|
||||
{
|
||||
empty = val;
|
||||
}
|
||||
|
||||
public void setFoo(String val)
|
||||
{
|
||||
foo = val;
|
||||
}
|
||||
|
||||
public String getFoo()
|
||||
{
|
||||
return foo;
|
||||
}
|
||||
|
||||
public String getBah()
|
||||
{
|
||||
return bah;
|
||||
}
|
||||
|
||||
public void setBah(String val)
|
||||
{
|
||||
bah = val;
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
context = new WebAppContext();
|
||||
context.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), context));
|
||||
context.getServerClasspathPattern().add("-org.eclipse.jetty.plus.webapp."); //need visbility of the TestInjections class
|
||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||
Context icontext = new InitialContext();
|
||||
Context compCtx = (Context)icontext.lookup("java:comp");
|
||||
compCtx.createSubcontext("env");
|
||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||
Context envCtx = compCtx.createSubcontext("env");
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
org.eclipse.jetty.plus.jndi.Resource ds = new org.eclipse.jetty.plus.jndi.Resource(context, "jdbc/mydatasource", new Object());
|
||||
|
||||
//An EnvEntry that should override any value supplied in a web.xml file
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry fooStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("foo", "FOO", true);
|
||||
doEnvConfiguration(envCtx, fooStringEnvEntry);
|
||||
|
||||
//An EnvEntry that should NOT override any value supplied in a web.xml file
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry bahStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("bah", "BAH", false);
|
||||
doEnvConfiguration(envCtx, bahStringEnvEntry);
|
||||
|
||||
//An EnvEntry that will override an empty value in web.xml
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry emptyStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("empty", "EMPTY", true);
|
||||
doEnvConfiguration(envCtx, emptyStringEnvEntry);
|
||||
|
||||
//An EnvEntry that will NOT override an empty value in web.xml
|
||||
org.eclipse.jetty.plus.jndi.EnvEntry vacuumStringEnvEntry = new org.eclipse.jetty.plus.jndi.EnvEntry("vacuum", "VACUUM", false);
|
||||
doEnvConfiguration(envCtx, vacuumStringEnvEntry);
|
||||
|
||||
URL webXml = Thread.currentThread().getContextClassLoader().getResource("web.xml");
|
||||
webDescriptor = new WebDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(webXml));
|
||||
|
@ -85,6 +170,22 @@ public class PlusDescriptorProcessorTest
|
|||
URL frag4Xml = Thread.currentThread().getContextClassLoader().getResource("web-fragment-4.xml");
|
||||
fragDescriptor4 = new FragmentDescriptor(org.eclipse.jetty.util.resource.Resource.newResource(frag4Xml));
|
||||
fragDescriptor4.parse();
|
||||
|
||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the kind of processing that EnvConfiguration would do.
|
||||
*
|
||||
* @param envCtx the java:comp/env context
|
||||
* @param envEntry the EnvEntry
|
||||
* @throws Exception
|
||||
*/
|
||||
private void doEnvConfiguration(Context envCtx, EnvEntry envEntry) throws Exception
|
||||
{
|
||||
envEntry.bindToENC(envEntry.getJndiName());
|
||||
Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, envEntry);
|
||||
NamingUtil.bind(envCtx, namingEntryName.toString(), envEntry);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
@ -140,6 +241,59 @@ public class PlusDescriptorProcessorTest
|
|||
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnvEntries() throws Exception
|
||||
{
|
||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||
try
|
||||
{
|
||||
PlusDescriptorProcessor pdp = new PlusDescriptorProcessor();
|
||||
//process web.xml
|
||||
pdp.process(context, webDescriptor);
|
||||
InjectionCollection injections = (InjectionCollection)context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
|
||||
assertNotNull(injections);
|
||||
|
||||
//check that there is an injection for "foo" with the value from the overriding EnvEntry of "FOO"
|
||||
Injection foo = injections.getInjection("foo", TestInjections.class,
|
||||
IntrospectionUtil.findMethod(TestInjections.class, "setFoo", STRING_ARG, false, true),
|
||||
String.class);
|
||||
assertNotNull(foo);
|
||||
assertEquals("FOO", foo.lookupInjectedValue());
|
||||
|
||||
//check that there is an injection for "bah" with the value from web.xml of "beer"
|
||||
Injection bah = injections.getInjection("bah", TestInjections.class,
|
||||
IntrospectionUtil.findMethod(TestInjections.class, "setBah", STRING_ARG, false, true),
|
||||
String.class);
|
||||
assertNotNull(bah);
|
||||
assertEquals("beer", bah.lookupInjectedValue());
|
||||
|
||||
//check that there is an injection for "empty" with the value from the overriding EnvEntry of "EMPTY"
|
||||
Injection empty = injections.getInjection("empty", TestInjections.class,
|
||||
IntrospectionUtil.findMethod(TestInjections.class, "setEmpty", STRING_ARG, false, true),
|
||||
String.class);
|
||||
assertNotNull(empty);
|
||||
assertEquals("EMPTY", empty.lookupInjectedValue());
|
||||
|
||||
//check that there is NOT an injection for "vacuum"
|
||||
Injection vacuum = injections.getInjection("vacuum", TestInjections.class,
|
||||
IntrospectionUtil.findMethod(TestInjections.class, "setVacuum", STRING_ARG, false, true),
|
||||
String.class);
|
||||
assertNull(vacuum);
|
||||
|
||||
//check that there is an injection for "webxmlonly" with the value from web.xml of "WEBXMLONLY"
|
||||
Injection webXmlOnly = injections.getInjection("webxmlonly", TestInjections.class,
|
||||
IntrospectionUtil.findMethod(TestInjections.class, "setWebXmlOnly", STRING_ARG, false, true),
|
||||
String.class);
|
||||
assertNotNull(webXmlOnly);
|
||||
assertEquals("WEBXMLONLY", webXmlOnly.lookupInjectedValue());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMismatchedFragmentResourceDeclarations()
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.plus.webapp;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.webapp.MetaData;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class TestConfiguration
|
||||
{
|
||||
@Test
|
||||
public void testIt() throws Exception
|
||||
{
|
||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
try
|
||||
{
|
||||
InitialContext ic = new InitialContext();
|
||||
|
||||
Server server = new Server();
|
||||
|
||||
WebAppContext wac = new WebAppContext();
|
||||
wac.setServer(server);
|
||||
wac.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), wac));
|
||||
|
||||
MetaData metaData = new MetaData();
|
||||
|
||||
PlusDescriptorProcessor plusProcessor = new PlusDescriptorProcessor();
|
||||
|
||||
//bind some EnvEntrys at the server level
|
||||
EnvEntry ee1 = new EnvEntry(server, "xxx/a", "100", true);
|
||||
EnvEntry ee2 = new EnvEntry(server, "yyy/b", "200", false);
|
||||
EnvEntry ee3 = new EnvEntry(server, "zzz/c", "300", false);
|
||||
EnvEntry ee4 = new EnvEntry(server, "zzz/d", "400", false);
|
||||
EnvEntry ee5 = new EnvEntry(server, "zzz/f", "500", true);
|
||||
|
||||
//bind some EnvEntrys at the webapp level
|
||||
EnvEntry ee6 = new EnvEntry(wac, "xxx/a", "900", true);
|
||||
EnvEntry ee7 = new EnvEntry(wac, "yyy/b", "910", true);
|
||||
EnvEntry ee8 = new EnvEntry(wac, "zzz/c", "920", false);
|
||||
EnvEntry ee9 = new EnvEntry(wac, "zzz/e", "930", false);
|
||||
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "xxx/a"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "yyy/b"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/c"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(server, "zzz/d"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "xxx/a"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "yyy/b"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/c"));
|
||||
assertNotNull(NamingEntryUtil.lookupNamingEntry(wac, "zzz/e"));
|
||||
|
||||
//make a new env configuration
|
||||
EnvConfiguration envConfig = new EnvConfiguration();
|
||||
|
||||
Thread.currentThread().setContextClassLoader(wac.getClassLoader());
|
||||
MetaData metadata = new MetaData();
|
||||
envConfig.preConfigure(wac);
|
||||
envConfig.configure(wac);
|
||||
envConfig.bindEnvEntries(wac);
|
||||
|
||||
String val = (String)ic.lookup("java:comp/env/xxx/a");
|
||||
assertEquals("900", val); //webapp naming overrides server
|
||||
val = (String)ic.lookup("java:comp/env/yyy/b");
|
||||
assertEquals("910", val);//webapp overrides server
|
||||
val = (String)ic.lookup("java:comp/env/zzz/c");
|
||||
assertEquals("920", val);//webapp overrides server
|
||||
val = (String)ic.lookup("java:comp/env/zzz/d");
|
||||
assertEquals("400", val);//from server naming
|
||||
val = (String)ic.lookup("java:comp/env/zzz/e");
|
||||
assertEquals("930", val);//from webapp naming
|
||||
|
||||
NamingEntry ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/xxx/a");
|
||||
assertNotNull(ne);
|
||||
ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/yyy/b");
|
||||
assertNotNull(ne);
|
||||
ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/c");
|
||||
assertNotNull(ne);
|
||||
ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/d");
|
||||
assertNotNull(ne);
|
||||
ne = (NamingEntry)ic.lookup("java:comp/env/" + NamingEntry.__contextName + "/zzz/e");
|
||||
assertNotNull(ne);
|
||||
|
||||
plusProcessor.bindEnvEntry("foo", "99");
|
||||
assertEquals("99", ic.lookup("java:comp/env/foo"));
|
||||
|
||||
plusProcessor.bindEnvEntry("xxx/a", "7");
|
||||
assertEquals("900", ic.lookup("java:comp/env/xxx/a")); //webapp overrides web.xml
|
||||
plusProcessor.bindEnvEntry("yyy/b", "7");
|
||||
assertEquals("910", ic.lookup("java:comp/env/yyy/b"));//webapp overrides web.xml
|
||||
plusProcessor.bindEnvEntry("zzz/c", "7");
|
||||
assertEquals("7", ic.lookup("java:comp/env/zzz/c"));//webapp does NOT override web.xml
|
||||
plusProcessor.bindEnvEntry("zzz/d", "7");
|
||||
assertEquals("7", ic.lookup("java:comp/env/zzz/d"));//server does NOT override web.xml
|
||||
plusProcessor.bindEnvEntry("zzz/e", "7");
|
||||
assertEquals("7", ic.lookup("java:comp/env/zzz/e"));//webapp does NOT override web.xml
|
||||
plusProcessor.bindEnvEntry("zzz/f", "7");
|
||||
assertEquals("500", ic.lookup("java:comp/env/zzz/f"));//server overrides web.xml
|
||||
|
||||
((Context)ic.lookup("java:comp")).destroySubcontext("env");
|
||||
ic.destroySubcontext("xxx");
|
||||
ic.destroySubcontext("yyy");
|
||||
ic.destroySubcontext("zzz");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,20 +4,70 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
metadata-complete="false"
|
||||
version="3.0">
|
||||
version="3.0">
|
||||
|
||||
<display-name>Test WebApp</display-name>
|
||||
<display-name>Test WebApp</display-name>
|
||||
|
||||
<resource-ref>
|
||||
<res-ref-name>jdbc/mydatasource</res-ref-name>
|
||||
<res-type>javax.sql.DataSource</res-type>
|
||||
<res-auth>Container</res-auth>
|
||||
<!--
|
||||
<injection-target>
|
||||
<injection-target-class>com.acme.JNDITest</injection-target-class>
|
||||
<injection-target-name>myDatasource</injection-target-name>
|
||||
</injection-target>
|
||||
-->
|
||||
<!-- <injection-target> <injection-target-class>com.acme.JNDITest</injection-target-class>
|
||||
<injection-target-name>myDatasource</injection-target-name> </injection-target> -->
|
||||
</resource-ref>
|
||||
|
||||
<!-- env entry for which is there is an overriding EnvEntry -->
|
||||
<env-entry>
|
||||
<env-entry-name>foo</env-entry-name>
|
||||
<env-entry-type>java.lang.String</env-entry-type>
|
||||
<env-entry-value>beer</env-entry-value>
|
||||
<injection-target>
|
||||
<injection-target-class>org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections</injection-target-class>
|
||||
<injection-target-name>foo</injection-target-name>
|
||||
</injection-target>
|
||||
</env-entry>
|
||||
|
||||
<!-- env entry for which the EnvEntry does not override -->
|
||||
<env-entry>
|
||||
<env-entry-name>bah</env-entry-name>
|
||||
<env-entry-type>java.lang.String</env-entry-type>
|
||||
<env-entry-value>beer</env-entry-value>
|
||||
<injection-target>
|
||||
<injection-target-class>org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections</injection-target-class>
|
||||
<injection-target-name>bah</injection-target-name>
|
||||
</injection-target>
|
||||
</env-entry>
|
||||
|
||||
<!-- env entry with no value for which the EnvEntry should override -->
|
||||
<env-entry>
|
||||
<env-entry-name>empty</env-entry-name>
|
||||
<env-entry-type>java.lang.String</env-entry-type>
|
||||
<env-entry-value></env-entry-value>
|
||||
<injection-target>
|
||||
<injection-target-class>org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections</injection-target-class>
|
||||
<injection-target-name>empty</injection-target-name>
|
||||
</injection-target>
|
||||
</env-entry>
|
||||
|
||||
<!-- env entry with no value and EnvEntry does not override -->
|
||||
<env-entry>
|
||||
<env-entry-name>vacuum</env-entry-name>
|
||||
<env-entry-type>java.lang.String</env-entry-type>
|
||||
<env-entry-value></env-entry-value>
|
||||
<injection-target>
|
||||
<injection-target-class>org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections</injection-target-class>
|
||||
<injection-target-name>vacuum</injection-target-name>
|
||||
</injection-target>
|
||||
</env-entry>
|
||||
|
||||
<!-- env entry with no matching EnvEntry -->
|
||||
<env-entry>
|
||||
<env-entry-name>webxmlonly</env-entry-name>
|
||||
<env-entry-type>java.lang.String</env-entry-type>
|
||||
<env-entry-value>WEBXMLONLY</env-entry-value>
|
||||
<injection-target>
|
||||
<injection-target-class>org.eclipse.jetty.plus.webapp.PlusDescriptorProcessorTest$TestInjections</injection-target-class>
|
||||
<injection-target-name>webXmlOnly</injection-target-name>
|
||||
</injection-target>
|
||||
</env-entry>
|
||||
</web-app>
|
||||
|
|
|
@ -1,8 +1,27 @@
|
|||
<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||
|
||||
<!-- =============================================================== --><!-- Documentation of this file format can be found at: --><!-- https://www.eclipse.org/jetty/documentation/current/ --><!-- --><!-- Additional configuration files are available in $JETTY_HOME/etc --><!-- and can be mixed in. See start.ini file for the default --><!-- configuration files. --><!-- --><!-- For a description of the configuration mechanism, see the --><!-- output of: --><!-- java -jar start.jar -? --><!-- =============================================================== -->
|
||||
<!-- =============================================================== -->
|
||||
<!-- Documentation of this file format can be found at: -->
|
||||
<!-- https://www.eclipse.org/jetty/documentation/current/ -->
|
||||
<!-- -->
|
||||
<!-- Additional configuration files are available in $JETTY_HOME/etc -->
|
||||
<!-- and can be mixed in. See start.ini file for the default -->
|
||||
<!-- configuration files. -->
|
||||
<!-- -->
|
||||
<!-- For a description of the configuration mechanism, see the -->
|
||||
<!-- output of: -->
|
||||
<!-- java -jar start.jar -? -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
<!-- =============================================================== --><!-- Configure a Jetty Server instance with an ID "Server" --><!-- Other configuration files may also configure the "Server" --><!-- ID, in which case they are adding configuration to the same --><!-- instance. If other configuration have a different ID, they --><!-- will create and configure another instance of Jetty. --><!-- Consult the javadoc of o.e.j.server.Server for all --><!-- configuration that may be set here. --><!-- =============================================================== -->
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure a Jetty Server instance with an ID "Server" -->
|
||||
<!-- Other configuration files may also configure the "Server" -->
|
||||
<!-- ID, in which case they are adding configuration to the same -->
|
||||
<!-- instance. If other configuration have a different ID, they -->
|
||||
<!-- will create and configure another instance of Jetty. -->
|
||||
<!-- Consult the javadoc of o.e.j.server.Server for all -->
|
||||
<!-- configuration that may be set here. -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
<Arg name="threadpool"><Ref refid="threadPool"/></Arg>
|
||||
|
||||
|
|
|
@ -1029,12 +1029,16 @@ public class CustomRequestLog extends ContainerLifeCycle implements RequestLog
|
|||
|
||||
private static void logRequestCookie(String arg, StringBuilder b, Request request, Response response)
|
||||
{
|
||||
for (Cookie c : request.getCookies())
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null)
|
||||
{
|
||||
if (arg.equals(c.getName()))
|
||||
for (Cookie c : cookies)
|
||||
{
|
||||
b.append(c.getValue());
|
||||
return;
|
||||
if (arg.equals(c.getName()))
|
||||
{
|
||||
b.append(c.getValue());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.lang.invoke.MethodType;
|
|||
import java.net.InetSocketAddress;
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.eclipse.jetty.http.BadMessageException;
|
||||
import org.eclipse.jetty.http.HostPortHttpField;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
|
@ -376,18 +377,18 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
|
||||
// Do a single pass through the header fields as it is a more efficient single iteration.
|
||||
Forwarded forwarded = new Forwarded(request, config);
|
||||
try
|
||||
for (HttpField field : httpFields)
|
||||
{
|
||||
for (HttpField field : httpFields)
|
||||
try
|
||||
{
|
||||
MethodHandle handle = _handles.get(field.getName());
|
||||
if (handle != null)
|
||||
handle.invoke(forwarded, field);
|
||||
}
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
catch (Throwable t)
|
||||
{
|
||||
onError(field, t);
|
||||
}
|
||||
}
|
||||
|
||||
if (forwarded._proto != null)
|
||||
|
@ -420,6 +421,11 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
}
|
||||
}
|
||||
|
||||
protected void onError(HttpField field, Throwable t)
|
||||
{
|
||||
throw new BadMessageException("Bad header value for " + field.getName(), t);
|
||||
}
|
||||
|
||||
protected String getLeftMost(String headerValue)
|
||||
{
|
||||
if (headerValue == null)
|
||||
|
@ -623,35 +629,37 @@ public class ForwardedRequestCustomizer implements Customizer
|
|||
@SuppressWarnings("unused")
|
||||
public void handleFor(HttpField field)
|
||||
{
|
||||
String authority = getLeftMost(field.getValue());
|
||||
if (!getForwardedPortAsAuthority() && !StringUtil.isEmpty(getForwardedPortHeader()))
|
||||
{
|
||||
if (_for == null)
|
||||
_for = new PossiblyPartialHostPort(getLeftMost(field.getValue()));
|
||||
_for = new PossiblyPartialHostPort(authority);
|
||||
else if (_for instanceof PortSetHostPort)
|
||||
_for = new HostPort(HostPort.normalizeHost(getLeftMost(field.getValue())), _for.getPort());
|
||||
_for = new HostPort(HostPort.normalizeHost(authority), _for.getPort());
|
||||
}
|
||||
else if (_for == null)
|
||||
{
|
||||
_for = new HostPort(getLeftMost(field.getValue()));
|
||||
_for = new HostPort(authority);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handlePort(HttpField field)
|
||||
{
|
||||
int port = HostPort.parsePort(getLeftMost(field.getValue()));
|
||||
if (!getForwardedPortAsAuthority())
|
||||
{
|
||||
if (_for == null)
|
||||
_for = new PortSetHostPort(_request.getRemoteHost(), Integer.parseInt(getLeftMost(field.getValue())));
|
||||
_for = new PortSetHostPort(_request.getRemoteHost(), port);
|
||||
else if (_for instanceof PossiblyPartialHostPort && _for.getPort() <= 0)
|
||||
_for = new HostPort(HostPort.normalizeHost(_for.getHost()), Integer.parseInt(getLeftMost(field.getValue())));
|
||||
_for = new HostPort(HostPort.normalizeHost(_for.getHost()), port);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_host == null)
|
||||
_host = new PortSetHostPort(_request.getServerName(), Integer.parseInt(getLeftMost(field.getValue())));
|
||||
_host = new PortSetHostPort(_request.getServerName(), port);
|
||||
else if (_host instanceof PossiblyPartialHostPort && _host.getPort() <= 0)
|
||||
_host = new HostPort(HostPort.normalizeHost(_host.getHost()), Integer.parseInt(getLeftMost(field.getValue())));
|
||||
_host = new HostPort(HostPort.normalizeHost(_host.getHost()), port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -708,8 +708,16 @@ public class DetectorConnectionTest
|
|||
sb.append("AAAA");
|
||||
}
|
||||
String request = sb.toString();
|
||||
String response = getResponse(request);
|
||||
|
||||
assertThat(response, Matchers.nullValue());
|
||||
try
|
||||
{
|
||||
String response = getResponse(request);
|
||||
assertThat(response, Matchers.nullValue());
|
||||
}
|
||||
catch (SocketException expected)
|
||||
{
|
||||
// The test may fail writing the "request"
|
||||
// bytes as the server sends back a TCP RST.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.jetty.http.HttpTester;
|
|||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
@ -619,6 +620,25 @@ public class ForwardedRequestCustomizerTest
|
|||
expectations.accept(actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadInput() throws Exception
|
||||
{
|
||||
Request request = new Request("Bad port value")
|
||||
.headers(
|
||||
"GET / HTTP/1.1",
|
||||
"Host: myhost",
|
||||
"X-Forwarded-Port: "
|
||||
);
|
||||
|
||||
request.configure(customizer);
|
||||
|
||||
String rawRequest = request.getRawRequest((header) -> header);
|
||||
System.out.println(rawRequest);
|
||||
|
||||
HttpTester.Response response = HttpTester.parseResponse(connector.getResponse(rawRequest));
|
||||
assertThat("status", response.getStatus(), is(400));
|
||||
}
|
||||
|
||||
private static class Request
|
||||
{
|
||||
String description;
|
||||
|
|
|
@ -23,7 +23,9 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.servlet.Filter;
|
||||
|
@ -157,8 +159,10 @@ public class CrossOriginFilter implements Filter
|
|||
private boolean anyOriginAllowed;
|
||||
private boolean anyTimingOriginAllowed;
|
||||
private boolean anyHeadersAllowed;
|
||||
private List<String> allowedOrigins = new ArrayList<String>();
|
||||
private List<String> allowedTimingOrigins = new ArrayList<String>();
|
||||
private Set<String> allowedOrigins = new HashSet<String>();
|
||||
private List<Pattern> allowedOriginPatterns = new ArrayList<Pattern>();
|
||||
private Set<String> allowedTimingOrigins = new HashSet<String>();
|
||||
private List<Pattern> allowedTimingOriginPatterns = new ArrayList<Pattern>();
|
||||
private List<String> allowedMethods = new ArrayList<String>();
|
||||
private List<String> allowedHeaders = new ArrayList<String>();
|
||||
private List<String> exposedHeaders = new ArrayList<String>();
|
||||
|
@ -172,8 +176,8 @@ public class CrossOriginFilter implements Filter
|
|||
String allowedOriginsConfig = config.getInitParameter(ALLOWED_ORIGINS_PARAM);
|
||||
String allowedTimingOriginsConfig = config.getInitParameter(ALLOWED_TIMING_ORIGINS_PARAM);
|
||||
|
||||
anyOriginAllowed = generateAllowedOrigins(allowedOrigins, allowedOriginsConfig, DEFAULT_ALLOWED_ORIGINS);
|
||||
anyTimingOriginAllowed = generateAllowedOrigins(allowedTimingOrigins, allowedTimingOriginsConfig, DEFAULT_ALLOWED_TIMING_ORIGINS);
|
||||
anyOriginAllowed = generateAllowedOrigins(allowedOrigins, allowedOriginPatterns, allowedOriginsConfig, DEFAULT_ALLOWED_ORIGINS);
|
||||
anyTimingOriginAllowed = generateAllowedOrigins(allowedTimingOrigins, allowedTimingOriginPatterns, allowedTimingOriginsConfig, DEFAULT_ALLOWED_TIMING_ORIGINS);
|
||||
|
||||
String allowedMethodsConfig = config.getInitParameter(ALLOWED_METHODS_PARAM);
|
||||
if (allowedMethodsConfig == null)
|
||||
|
@ -235,7 +239,7 @@ public class CrossOriginFilter implements Filter
|
|||
}
|
||||
}
|
||||
|
||||
private boolean generateAllowedOrigins(List<String> allowedOriginStore, String allowedOriginsConfig, String defaultOrigin)
|
||||
private boolean generateAllowedOrigins(Set<String> allowedOriginStore, List<Pattern> allowedOriginPatternStore, String allowedOriginsConfig, String defaultOrigin)
|
||||
{
|
||||
if (allowedOriginsConfig == null)
|
||||
allowedOriginsConfig = defaultOrigin;
|
||||
|
@ -247,8 +251,13 @@ public class CrossOriginFilter implements Filter
|
|||
if (ANY_ORIGIN.equals(allowedOrigin))
|
||||
{
|
||||
allowedOriginStore.clear();
|
||||
allowedOriginPatternStore.clear();
|
||||
return true;
|
||||
}
|
||||
else if (allowedOrigin.contains("*"))
|
||||
{
|
||||
allowedOriginPatternStore.add(Pattern.compile(parseAllowedWildcardOriginToRegex(allowedOrigin)));
|
||||
}
|
||||
else
|
||||
{
|
||||
allowedOriginStore.add(allowedOrigin);
|
||||
|
@ -270,7 +279,7 @@ public class CrossOriginFilter implements Filter
|
|||
// Is it a cross origin request ?
|
||||
if (origin != null && isEnabled(request))
|
||||
{
|
||||
if (anyOriginAllowed || originMatches(allowedOrigins, origin))
|
||||
if (anyOriginAllowed || originMatches(allowedOrigins, allowedOriginPatterns, origin))
|
||||
{
|
||||
if (isSimpleRequest(request))
|
||||
{
|
||||
|
@ -292,7 +301,7 @@ public class CrossOriginFilter implements Filter
|
|||
handleSimpleResponse(request, response, origin);
|
||||
}
|
||||
|
||||
if (anyTimingOriginAllowed || originMatches(allowedTimingOrigins, origin))
|
||||
if (anyTimingOriginAllowed || originMatches(allowedTimingOrigins, allowedTimingOriginPatterns, origin))
|
||||
{
|
||||
response.setHeader(TIMING_ALLOW_ORIGIN_HEADER, origin);
|
||||
}
|
||||
|
@ -330,7 +339,7 @@ public class CrossOriginFilter implements Filter
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean originMatches(List<String> allowedOrigins, String originList)
|
||||
private boolean originMatches(Set<String> allowedOrigins, List<Pattern> allowedOriginPatterns, String originList)
|
||||
{
|
||||
if (originList.trim().length() == 0)
|
||||
return false;
|
||||
|
@ -341,30 +350,18 @@ public class CrossOriginFilter implements Filter
|
|||
if (origin.trim().length() == 0)
|
||||
continue;
|
||||
|
||||
for (String allowedOrigin : allowedOrigins)
|
||||
if (allowedOrigins.contains(origin))
|
||||
return true;
|
||||
|
||||
for (Pattern allowedOrigin : allowedOriginPatterns)
|
||||
{
|
||||
if (allowedOrigin.contains("*"))
|
||||
{
|
||||
Matcher matcher = createMatcher(origin, allowedOrigin);
|
||||
if (matcher.matches())
|
||||
return true;
|
||||
}
|
||||
else if (allowedOrigin.equals(origin))
|
||||
{
|
||||
if (allowedOrigin.matcher(origin).matches())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Matcher createMatcher(String origin, String allowedOrigin)
|
||||
{
|
||||
String regex = parseAllowedWildcardOriginToRegex(allowedOrigin);
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
return pattern.matcher(origin);
|
||||
}
|
||||
|
||||
private String parseAllowedWildcardOriginToRegex(String allowedOrigin)
|
||||
{
|
||||
String regex = StringUtil.replace(allowedOrigin, ".", "\\.");
|
||||
|
@ -505,7 +502,11 @@ public class CrossOriginFilter implements Filter
|
|||
public void destroy()
|
||||
{
|
||||
anyOriginAllowed = false;
|
||||
anyTimingOriginAllowed = false;
|
||||
allowedOrigins.clear();
|
||||
allowedOriginPatterns.clear();
|
||||
allowedTimingOrigins.clear();
|
||||
allowedTimingOriginPatterns.clear();
|
||||
allowedMethods.clear();
|
||||
allowedHeaders.clear();
|
||||
preflightMaxAge = 0;
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.9.v20160720|lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.9.v20160720.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.10.v20161026|lib/alpn/alpn-boot-8.1.10.v20161026.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.10.v20161026.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.11.v20170118|lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.11.v20170118.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.12.v20180117|lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.12.v20180117.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
|
@ -1,5 +0,0 @@
|
|||
[files]
|
||||
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.13.v20181017|lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
||||
|
||||
[exec]
|
||||
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.13.v20181017.jar
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue