Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimone Bordet2014-03-20 15:22:43 +0000
committerSimone Bordet2014-03-20 15:22:43 +0000
commitb994db698c8e223c92444a49d1fdfb2c27559b04 (patch)
tree8457dbfeb21562ce7438a4eb87465d91318eaf00
parent48c803b6933524fc6581652ff8c18ff4bfbb9f5a (diff)
downloadorg.eclipse.jetty.project-b994db698c8e223c92444a49d1fdfb2c27559b04.tar.gz
org.eclipse.jetty.project-b994db698c8e223c92444a49d1fdfb2c27559b04.tar.xz
org.eclipse.jetty.project-b994db698c8e223c92444a49d1fdfb2c27559b04.zip
Refactored NPN code for the soon-to-arrive ALPN code.
Moved NPN tests to new module spdy-npn-tests, that now is the only module requiring the -Xbootclasspath configuration for the Maven Surefire Plugin.
-rw-r--r--examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyConnector.java2
-rw-r--r--examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java2
-rw-r--r--jetty-spdy/pom.xml26
-rw-r--r--jetty-spdy/spdy-client/pom.xml30
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java107
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java19
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnection.java133
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnectionFactory.java36
-rw-r--r--jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java30
-rw-r--r--jetty-spdy/spdy-http-client-transport/pom.xml30
-rw-r--r--jetty-spdy/spdy-http-server/pom.xml33
-rw-r--r--jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java27
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java14
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ProtocolNegotiationTest.java255
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java35
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java46
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java35
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java32
-rw-r--r--jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java29
-rw-r--r--jetty-spdy/spdy-npn-tests/pom.xml95
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java77
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java (renamed from jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/NpnModuleTest.java)19
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java207
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java (renamed from jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java)36
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java (renamed from jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java)34
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java29
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java27
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java27
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java27
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties2
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jks (renamed from jetty-spdy/spdy-server/src/test/resources/keystore.jks)bin2206 -> 2206 bytes
-rw-r--r--jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jks (renamed from jetty-spdy/spdy-server/src/test/resources/truststore.jks)bin916 -> 916 bytes
-rw-r--r--jetty-spdy/spdy-server/pom.xml30
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java115
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java87
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnection.java163
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnectionFactory.java103
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java29
-rw-r--r--jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java27
-rw-r--r--pom.xml262
-rw-r--r--tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java2
41 files changed, 1280 insertions, 1039 deletions
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyConnector.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyConnector.java
index 542197be78..05115382c7 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyConnector.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyConnector.java
@@ -72,7 +72,7 @@ public class SpdyConnector
new HTTPSPDYServerConnectionFactory(3,https_config,new ReferrerPushStrategy());
// NPN Factory
- SPDYServerConnectionFactory.checkNPNAvailable();
+ SPDYServerConnectionFactory.checkProtocolNegotiationAvailable();
NPNServerConnectionFactory npn =
new NPNServerConnectionFactory(spdy3.getProtocol(),spdy2.getProtocol(),http.getDefaultProtocol());
npn.setDefaultProtocol(http.getDefaultProtocol());
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java
index 3ab394230d..a9dfdc488f 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SpdyServer.java
@@ -110,7 +110,7 @@ public class SpdyServer
// Spdy Connector
// Make sure that the required NPN implementations are available.
- SPDYServerConnectionFactory.checkNPNAvailable();
+ SPDYServerConnectionFactory.checkProtocolNegotiationAvailable();
// A ReferrerPushStrategy is being initialized.
// See: http://www.eclipse.org/jetty/documentation/current/spdy-configuring-push.html for more details.
diff --git a/jetty-spdy/pom.xml b/jetty-spdy/pom.xml
index 61777c8750..d9f4e91da3 100644
--- a/jetty-spdy/pom.xml
+++ b/jetty-spdy/pom.xml
@@ -23,13 +23,17 @@
<module>spdy-example-webapp</module>
</modules>
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty.toolchain</groupId>
- <artifactId>jetty-test-helper</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
+ <profiles>
+ <profile>
+ <id>jdk7-npn</id>
+ <activation>
+ <jdk>[1.7,1.8)</jdk>
+ </activation>
+ <modules>
+ <module>spdy-npn-tests</module>
+ </modules>
+ </profile>
+ </profiles>
<build>
<plugins>
@@ -70,4 +74,12 @@
</plugins>
</build>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <artifactId>jetty-test-helper</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
</project>
diff --git a/jetty-spdy/spdy-client/pom.xml b/jetty-spdy/spdy-client/pom.xml
index 4ec9956aa0..20bad8ff7b 100644
--- a/jetty-spdy/spdy-client/pom.xml
+++ b/jetty-spdy/spdy-client/pom.xml
@@ -18,36 +18,6 @@
<build>
<plugins>
<plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.mortbay.jetty.npn</groupId>
- <artifactId>npn-boot</artifactId>
- <version>${npn.version}</version>
- <type>jar</type>
- <overWrite>false</overWrite>
- <outputDirectory>${project.build.directory}/npn</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
- </configuration>
- </plugin>
- <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java
index fc288894d6..c8e85f2c0e 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnection.java
@@ -18,87 +18,28 @@
package org.eclipse.jetty.spdy.client;
-import java.io.IOException;
import java.util.List;
import java.util.Map;
-
+import java.util.concurrent.Executor;
import javax.net.ssl.SSLEngine;
-import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ClientConnectionFactory;
-import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-public class NPNClientConnection extends AbstractConnection implements NextProtoNego.ClientProvider
+public class NPNClientConnection extends NegotiatingClientConnection implements NextProtoNego.ClientProvider
{
- private final Logger LOG = Log.getLogger(getClass());
- private final SPDYClient client;
- private final ClientConnectionFactory connectionFactory;
- private final SSLEngine engine;
- private final Map<String, Object> context;
- private volatile boolean completed;
+ private static final Logger LOG = Log.getLogger(NPNClientConnection.class);
- public NPNClientConnection(EndPoint endPoint, SPDYClient client, ClientConnectionFactory connectionFactory, SSLEngine sslEngine, Map<String, Object> context)
- {
- super(endPoint, client.getFactory().getExecutor());
- this.client = client;
- this.connectionFactory = connectionFactory;
- this.engine = sslEngine;
- this.context = context;
- NextProtoNego.put(engine, this);
- }
+ private final String protocol;
- @Override
- public void onOpen()
+ public NPNClientConnection(EndPoint endPoint, Executor executor, ClientConnectionFactory connectionFactory, SSLEngine sslEngine, Map<String, Object> context, String protocol)
{
- super.onOpen();
- try
- {
- getEndPoint().flush(BufferUtil.EMPTY_BUFFER);
- if (completed)
- replaceConnection();
- else
- fillInterested();
- }
- catch(IOException e)
- {
- throw new RuntimeIOException(e);
- }
- }
-
- @Override
- public void onFillable()
- {
- while (true)
- {
- int filled = fill();
- if (filled == 0 && !completed)
- fillInterested();
- if (filled <= 0 || completed)
- break;
- }
- if (completed)
- replaceConnection();
- }
-
- private int fill()
- {
- try
- {
- return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
- }
- catch (IOException x)
- {
- LOG.debug(x);
- NextProtoNego.remove(engine);
- close();
- return -1;
- }
+ super(endPoint, executor, sslEngine, connectionFactory, context);
+ this.protocol = protocol;
+ NextProtoNego.put(sslEngine, this);
}
@Override
@@ -110,31 +51,31 @@ public class NPNClientConnection extends AbstractConnection implements NextProto
@Override
public void unsupported()
{
- NextProtoNego.remove(engine);
- completed = true;
+ NextProtoNego.remove(getSSLEngine());
+ completed();
}
@Override
public String selectProtocol(List<String> protocols)
{
- NextProtoNego.remove(engine);
- completed = true;
- return client.selectProtocol(protocols);
- }
-
- private void replaceConnection()
- {
- EndPoint endPoint = getEndPoint();
- try
+ if (protocols.contains(protocol))
{
- Connection oldConnection = endPoint.getConnection();
- Connection newConnection = connectionFactory.newConnection(endPoint, context);
- ClientConnectionFactory.Helper.replaceConnection(oldConnection, newConnection);
+ NextProtoNego.remove(getSSLEngine());
+ completed();
+ return protocol;
}
- catch (Throwable x)
+ else
{
- LOG.debug(x);
+ LOG.info("Could not negotiate protocol: server {} - client {}", protocols, protocol);
close();
+ return null;
}
}
+
+ @Override
+ public void close()
+ {
+ NextProtoNego.remove(getSSLEngine());
+ super.close();
+ }
}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java
index ec81cab156..d0458010c9 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NPNClientConnectionFactory.java
@@ -20,7 +20,7 @@ package org.eclipse.jetty.spdy.client;
import java.io.IOException;
import java.util.Map;
-
+import java.util.concurrent.Executor;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.io.ClientConnectionFactory;
@@ -28,21 +28,22 @@ import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
-public class NPNClientConnectionFactory implements ClientConnectionFactory
+public class NPNClientConnectionFactory extends NegotiatingClientConnectionFactory
{
- private final SPDYClient client;
- private final ClientConnectionFactory connectionFactory;
+ private final Executor executor;
+ private final String protocol;
- public NPNClientConnectionFactory(SPDYClient client, ClientConnectionFactory connectionFactory)
+ public NPNClientConnectionFactory(Executor executor, ClientConnectionFactory connectionFactory, String protocol)
{
- this.client = client;
- this.connectionFactory = connectionFactory;
+ super(connectionFactory);
+ this.executor = executor;
+ this.protocol = protocol;
}
@Override
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
{
- return new NPNClientConnection(endPoint, client, connectionFactory,
- (SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY), context);
+ return new NPNClientConnection(endPoint, executor, getClientConnectionFactory(),
+ (SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY), context, protocol);
}
}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnection.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnection.java
new file mode 100644
index 0000000000..a2fc8511f4
--- /dev/null
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnection.java
@@ -0,0 +1,133 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.client;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import javax.net.ssl.SSLEngine;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.ClientConnectionFactory;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RuntimeIOException;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public abstract class NegotiatingClientConnection extends AbstractConnection
+{
+ private static final Logger LOG = Log.getLogger(NegotiatingClientConnection.class);
+
+ private final SSLEngine engine;
+ private final ClientConnectionFactory connectionFactory;
+ private final Map<String, Object> context;
+ private volatile boolean completed;
+
+ protected NegotiatingClientConnection(EndPoint endp, Executor executor, SSLEngine sslEngine, ClientConnectionFactory connectionFactory, Map<String, Object> context)
+ {
+ super(endp, executor);
+ this.engine = sslEngine;
+ this.connectionFactory = connectionFactory;
+ this.context = context;
+ }
+
+ protected SSLEngine getSSLEngine()
+ {
+ return engine;
+ }
+
+ protected void completed()
+ {
+ completed = true;
+ }
+
+ @Override
+ public void onOpen()
+ {
+ super.onOpen();
+ try
+ {
+ getEndPoint().flush(BufferUtil.EMPTY_BUFFER);
+ if (completed)
+ replaceConnection();
+ else
+ fillInterested();
+ }
+ catch (IOException x)
+ {
+ close();
+ throw new RuntimeIOException(x);
+ }
+ }
+
+ @Override
+ public void onFillable()
+ {
+ while (true)
+ {
+ int filled = fill();
+ if (filled == 0 && !completed)
+ fillInterested();
+ if (filled <= 0 || completed)
+ break;
+ }
+ if (completed)
+ replaceConnection();
+ }
+
+ private int fill()
+ {
+ try
+ {
+ return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
+ }
+ catch (IOException x)
+ {
+ LOG.debug(x);
+ close();
+ return -1;
+ }
+ }
+
+ private void replaceConnection()
+ {
+ EndPoint endPoint = getEndPoint();
+ try
+ {
+ Connection oldConnection = endPoint.getConnection();
+ Connection newConnection = connectionFactory.newConnection(endPoint, context);
+ ClientConnectionFactory.Helper.replaceConnection(oldConnection, newConnection);
+ }
+ catch (Throwable x)
+ {
+ LOG.debug(x);
+ close();
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ // Gentler close for SSL.
+ getEndPoint().shutdownOutput();
+ super.close();
+ }
+}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnectionFactory.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnectionFactory.java
new file mode 100644
index 0000000000..50a1e5b223
--- /dev/null
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/NegotiatingClientConnectionFactory.java
@@ -0,0 +1,36 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.client;
+
+import org.eclipse.jetty.io.ClientConnectionFactory;
+
+public abstract class NegotiatingClientConnectionFactory implements ClientConnectionFactory
+{
+ private final ClientConnectionFactory connectionFactory;
+
+ protected NegotiatingClientConnectionFactory(ClientConnectionFactory connectionFactory)
+ {
+ this.connectionFactory = connectionFactory;
+ }
+
+ public ClientConnectionFactory getClientConnectionFactory()
+ {
+ return connectionFactory;
+ }
+}
diff --git a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
index 678aa2aac6..d30bc99f4e 100644
--- a/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
+++ b/jetty-spdy/spdy-client/src/main/java/org/eclipse/jetty/spdy/client/SPDYClient.java
@@ -26,7 +26,6 @@ import java.nio.channels.SocketChannel;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -86,10 +85,6 @@ public class SPDYClient
this.factory = factory;
setInitialWindowSize(65536);
setDispatchIO(true);
- ClientConnectionFactory connectionFactory = new SPDYClientConnectionFactory();
- if (factory.sslContextFactory != null)
- connectionFactory = new SslClientConnectionFactory(factory.getSslContextFactory(), factory.getByteBufferPool(), factory.getExecutor(), new NPNClientConnectionFactory(this, connectionFactory));
- setClientConnectionFactory(connectionFactory);
}
public short getVersion()
@@ -239,17 +234,6 @@ public class SPDYClient
this.connectionFactory = connectionFactory;
}
- protected String selectProtocol(List<String> serverProtocols)
- {
- String protocol = "spdy/" + version;
- for (String serverProtocol : serverProtocols)
- {
- if (serverProtocol.equals(protocol))
- return protocol;
- }
- return null;
- }
-
protected FlowControlStrategy newFlowControlStrategy()
{
return FlowControlStrategyFactory.newFlowControlStrategy(version);
@@ -357,7 +341,19 @@ public class SPDYClient
public SPDYClient newSPDYClient(short version)
{
- return new SPDYClient(version, this);
+ return newSPDYClient(version, new NPNClientConnectionFactory(getExecutor(), new SPDYClientConnectionFactory(), "spdy/" + version));
+ }
+
+ public SPDYClient newSPDYClient(short version, NegotiatingClientConnectionFactory negotiatingFactory)
+ {
+ SPDYClient client = new SPDYClient(version, this);
+
+ ClientConnectionFactory connectionFactory = negotiatingFactory.getClientConnectionFactory();
+ if (sslContextFactory != null)
+ connectionFactory = new SslClientConnectionFactory(getSslContextFactory(), getByteBufferPool(), getExecutor(), negotiatingFactory);
+
+ client.setClientConnectionFactory(connectionFactory);
+ return client;
}
@Override
diff --git a/jetty-spdy/spdy-http-client-transport/pom.xml b/jetty-spdy/spdy-http-client-transport/pom.xml
index eb4fef0c14..61f978a4c5 100644
--- a/jetty-spdy/spdy-http-client-transport/pom.xml
+++ b/jetty-spdy/spdy-http-client-transport/pom.xml
@@ -17,36 +17,6 @@
<build>
<plugins>
<plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.mortbay.jetty.npn</groupId>
- <artifactId>npn-boot</artifactId>
- <version>${npn.version}</version>
- <type>jar</type>
- <overWrite>false</overWrite>
- <outputDirectory>${project.build.directory}/npn</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
- </configuration>
- </plugin>
- <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
diff --git a/jetty-spdy/spdy-http-server/pom.xml b/jetty-spdy/spdy-http-server/pom.xml
index 4555f19235..11740d8fa5 100644
--- a/jetty-spdy/spdy-http-server/pom.xml
+++ b/jetty-spdy/spdy-http-server/pom.xml
@@ -33,36 +33,19 @@
</executions>
</plugin>
<plugin>
- <artifactId>maven-dependency-plugin</artifactId>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
- <id>copy</id>
- <phase>generate-resources</phase>
+ <id>artifact-jars</id>
<goals>
- <goal>copy</goal>
+ <goal>jar</goal>
+ <goal>test-jar</goal>
</goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.mortbay.jetty.npn</groupId>
- <artifactId>npn-boot</artifactId>
- <version>${npn.version}</version>
- <type>jar</type>
- <overWrite>false</overWrite>
- <outputDirectory>${project.build.directory}/npn</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
</execution>
</executions>
</plugin>
<plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
- </configuration>
- </plugin>
- <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
@@ -128,12 +111,6 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-start</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
diff --git a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java
index c9d040a7aa..4c3015e6c1 100644
--- a/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java
+++ b/jetty-spdy/spdy-http-server/src/main/java/org/eclipse/jetty/spdy/server/proxy/HTTPSPDYProxyServerConnector.java
@@ -19,12 +19,14 @@
package org.eclipse.jetty.spdy.server.proxy;
-import org.eclipse.jetty.server.ConnectionFactory;
+import java.util.Objects;
+
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
+import org.eclipse.jetty.spdy.server.NegotiatingServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -37,7 +39,7 @@ public class HTTPSPDYProxyServerConnector extends ServerConnector
public HTTPSPDYProxyServerConnector(Server server, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector)
{
- this(server, null, config, proxyEngineSelector);
+ super(server, (SslContextFactory)null, new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector));
}
public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, ProxyEngineSelector proxyEngineSelector)
@@ -47,16 +49,15 @@ public class HTTPSPDYProxyServerConnector extends ServerConnector
public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector)
{
- super(server,
- sslContextFactory,
- sslContextFactory == null
- ? new ConnectionFactory[]{new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector)}
- : new ConnectionFactory[]{new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"),
- new SPDYServerConnectionFactory(SPDY.V3, proxyEngineSelector),
- new SPDYServerConnectionFactory(SPDY.V2, proxyEngineSelector),
- new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector)});
- NPNServerConnectionFactory npnConnectionFactory = getConnectionFactory(NPNServerConnectionFactory.class);
- if (npnConnectionFactory != null)
- npnConnectionFactory.setDefaultProtocol("http/1.1");
+ this(server, sslContextFactory, config, proxyEngineSelector, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
+ }
+
+ public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector, NegotiatingServerConnectionFactory negotiatingFactory)
+ {
+ super(server, Objects.requireNonNull(sslContextFactory), negotiatingFactory,
+ new SPDYServerConnectionFactory(SPDY.V3, proxyEngineSelector),
+ new SPDYServerConnectionFactory(SPDY.V2, proxyEngineSelector),
+ new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector));
+ negotiatingFactory.setDefaultProtocol("http/1.1");
}
}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java
index f82a58d1b2..cf3ac1cf0a 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/AbstractHTTPSPDYTest.java
@@ -73,11 +73,6 @@ public abstract class AbstractHTTPSPDYTest
this.version = version;
}
- protected InetSocketAddress startHTTPServer(Handler handler) throws Exception
- {
- return startHTTPServer(SPDY.V2, handler, 30000);
- }
-
protected InetSocketAddress startHTTPServer(short version, Handler handler, long idleTimeout) throws Exception
{
QueuedThreadPool threadPool = new QueuedThreadPool(256);
@@ -89,7 +84,6 @@ public abstract class AbstractHTTPSPDYTest
server.addConnector(connector);
server.setHandler(handler);
server.start();
- server.dumpStdErr();
return new InetSocketAddress("localhost", connector.getLocalPort());
}
@@ -104,13 +98,7 @@ public abstract class AbstractHTTPSPDYTest
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setSendServerVersion(true);
httpConfiguration.setSendXPoweredBy(true);
- HTTPSPDYServerConnector connector = new HTTPSPDYServerConnector(server,version, httpConfiguration, new PushStrategy.None());
- return connector;
- }
-
- protected Session startClient(InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
- {
- return startClient(SPDY.V2, socketAddress, listener);
+ return new HTTPSPDYServerConnector(server, version, httpConfiguration, new PushStrategy.None());
}
protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ProtocolNegotiationTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ProtocolNegotiationTest.java
deleted file mode 100644
index 5e9b3730fc..0000000000
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/http/ProtocolNegotiationTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
-// ------------------------------------------------------------------------
-// All rights reserved. This program and the accompanying materials
-// are made available under the terms of the Eclipse Public License v1.0
-// and Apache License v2.0 which accompanies this distribution.
-//
-// The Eclipse Public License is available at
-// http://www.eclipse.org/legal/epl-v10.html
-//
-// The Apache License v2.0 is available at
-// http://www.opensource.org/licenses/apache2.0.php
-//
-// You may elect to redistribute this code under either of these licenses.
-// ========================================================================
-//
-
-
-package org.eclipse.jetty.spdy.server.http;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-
-import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.spdy.server.SPDYServerConnector;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-
-public class ProtocolNegotiationTest
-{
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- protected Server server;
- protected SPDYServerConnector connector;
-
- protected InetSocketAddress startServer(SPDYServerConnector connector) throws Exception
- {
- server = new Server();
- if (connector == null)
- connector = new SPDYServerConnector(server, newSslContextFactory(), null);
- connector.setPort(0);
- connector.setIdleTimeout(30000);
- this.connector = connector;
- server.addConnector(connector);
- server.start();
- return new InetSocketAddress("localhost", connector.getLocalPort());
- }
-
- protected SslContextFactory newSslContextFactory()
- {
- SslContextFactory sslContextFactory = new SslContextFactory();
- sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
- sslContextFactory.setKeyStorePassword("storepwd");
- sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
- sslContextFactory.setTrustStorePassword("storepwd");
- sslContextFactory.setProtocol("TLSv1");
- sslContextFactory.setIncludeProtocols("TLSv1");
- return sslContextFactory;
- }
-
- @Test
- public void testServerAdvertisingHTTPSpeaksHTTP() throws Exception
- {
- InetSocketAddress address = startServer(null);
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort());
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- NextProtoNego.put(client, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> strings)
- {
- Assert.assertNotNull(strings);
- String protocol = "http/1.1";
- Assert.assertTrue(strings.contains(protocol));
- return protocol;
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
-
- client.close();
- }
-
- @Test
- public void testServerAdvertisingSPDYAndHTTPSpeaksHTTPWhenNegotiated() throws Exception
- {
- InetSocketAddress address = startServer(null);
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort());
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- NextProtoNego.put(client, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return true;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> strings)
- {
- Assert.assertNotNull(strings);
- String spdyProtocol = "spdy/2";
- Assert.assertTrue(strings.contains(spdyProtocol));
- String httpProtocol = "http/1.1";
- Assert.assertTrue(strings.contains(httpProtocol));
- Assert.assertTrue(strings.indexOf(spdyProtocol) < strings.indexOf(httpProtocol));
- return httpProtocol;
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
-
- client.close();
- }
-
- @Test
- public void testServerAdvertisingSPDYAndHTTPSpeaksDefaultProtocolWhenNPNMissing() throws Exception
- {
- InetSocketAddress address = startServer(null);
- connector.addConnectionFactory(new HttpConnectionFactory());
-
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.start();
- SSLContext sslContext = sslContextFactory.getSslContext();
- SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort());
- client.setUseClientMode(true);
- client.setSoTimeout(5000);
-
- NextProtoNego.put(client, new NextProtoNego.ClientProvider()
- {
- @Override
- public boolean supports()
- {
- return false;
- }
-
- @Override
- public void unsupported()
- {
- }
-
- @Override
- public String selectProtocol(List<String> strings)
- {
- return null;
- }
- });
-
- client.startHandshake();
-
- // Verify that the server really speaks http/1.1
-
- OutputStream output = client.getOutputStream();
- output.write(("" +
- "GET / HTTP/1.1\r\n" +
- "Host: localhost:" + address.getPort() + "\r\n" +
- "\r\n" +
- "").getBytes(StandardCharsets.UTF_8));
- output.flush();
-
- InputStream input = client.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
- String line = reader.readLine();
- Assert.assertTrue(line.contains(" 404 "));
-
- client.close();
- }
-}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java
index 8704e0de99..0f450e2ce6 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxyHTTPToSPDYTest.java
@@ -18,9 +18,6 @@
package org.eclipse.jetty.spdy.server.proxy;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@@ -53,49 +50,35 @@ import org.eclipse.jetty.spdy.client.SPDYClient;
import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
+import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.Promise;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
@RunWith(Parameterized.class)
public class ProxyHTTPToSPDYTest
{
- private static final Logger LOG = Log.getLogger(ProxyHTTPToSPDYTest.class);
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- private final short version;
- private HttpClient httpClient;
- private HttpClient httpClient2;
-
@Parameterized.Parameters
public static Collection<Short[]> parameters()
{
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
}
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ private final short version;
+ private HttpClient httpClient;
+ private HttpClient httpClient2;
private SPDYClient.Factory factory;
private Server server;
private Server proxy;
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java
index b2048a5acf..94e481becf 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPLoadTest.java
@@ -18,11 +18,6 @@
package org.eclipse.jetty.spdy.server.proxy;
-import static junit.framework.Assert.fail;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
@@ -38,13 +33,13 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -58,7 +53,9 @@ import org.eclipse.jetty.spdy.api.StreamFrameListener;
import org.eclipse.jetty.spdy.api.StringDataInfo;
import org.eclipse.jetty.spdy.api.SynInfo;
import org.eclipse.jetty.spdy.client.SPDYClient;
+import org.eclipse.jetty.spdy.server.NegotiatingServerConnectionFactory;
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
+import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.IO;
@@ -71,33 +68,19 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import static junit.framework.Assert.fail;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
@Ignore
@RunWith(value = Parameterized.class)
-public class ProxySPDYToHTTPLoadTest
+public abstract class ProxySPDYToHTTPLoadTest
{
private static final Logger LOG = Log.getLogger(ProxySPDYToHTTPLoadTest.class);
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- private final short version;
- private final String server1String = "server1";
- private final String server2String = "server2";
@Parameterized.Parameters
public static Collection<Short[]> parameters()
@@ -105,6 +88,12 @@ public class ProxySPDYToHTTPLoadTest
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
}
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ private final short version;
+ private final NegotiatingServerConnectionFactory negotiator;
+ private final String server1String = "server1";
+ private final String server2String = "server2";
private SPDYClient.Factory factory;
private Server server1;
private Server server2;
@@ -112,9 +101,10 @@ public class ProxySPDYToHTTPLoadTest
private ServerConnector proxyConnector;
private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
- public ProxySPDYToHTTPLoadTest(short version)
+ public ProxySPDYToHTTPLoadTest(short version, NegotiatingServerConnectionFactory negotiator)
{
this.version = version;
+ this.negotiator = negotiator;
}
@Before
@@ -188,7 +178,7 @@ public class ProxySPDYToHTTPLoadTest
proxyEngineSelector.putProxyServerInfo("127.0.0.2", new ProxyEngineSelector.ProxyServerInfo("http/1.1",
server2.getHostName(), server2.getPort()));
- proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, proxyEngineSelector);
+ proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, new HttpConfiguration(), proxyEngineSelector, negotiator);
proxyConnector.setPort(0);
proxyConnector.setIdleTimeout(proxyConnectorTimeout);
proxy.addConnector(proxyConnector);
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java
index 5363918601..700d560150 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToHTTPTest.java
@@ -18,11 +18,6 @@
package org.eclipse.jetty.spdy.server.proxy;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -32,7 +27,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -61,6 +55,7 @@ import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
import org.eclipse.jetty.spdy.client.SPDYClient;
import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
+import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.log.Log;
@@ -71,36 +66,26 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
@RunWith(value = Parameterized.class)
-public class ProxySPDYToHTTPTest
+public abstract class ProxySPDYToHTTPTest
{
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- private final short version;
-
@Parameterized.Parameters
public static Collection<Short[]> parameters()
{
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
}
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ private final short version;
private SPDYClient.Factory factory;
private Server server;
private Server proxy;
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java
index 1122185e0f..89f0eced80 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYLoadTest.java
@@ -18,10 +18,6 @@
package org.eclipse.jetty.spdy.server.proxy;
-import static junit.framework.Assert.fail;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
import java.io.ByteArrayOutputStream;
import java.net.InetSocketAddress;
import java.util.ArrayList;
@@ -52,6 +48,7 @@ import org.eclipse.jetty.spdy.client.SPDYClient;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
+import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -60,36 +57,25 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import static junit.framework.Assert.fail;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
@RunWith(value = Parameterized.class)
-public class ProxySPDYToSPDYLoadTest
+public abstract class ProxySPDYToSPDYLoadTest
{
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
-
- private final short version;
-
@Parameterized.Parameters
public static Collection<Short[]> parameters()
{
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
}
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ private final short version;
private static final String UUID_HEADER_NAME = "uuidHeader";
private static final String SERVER_ID_HEADER = "serverId";
private SPDYClient.Factory factory;
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java
index a3e1400b37..04e9551cd5 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java
+++ b/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/proxy/ProxySPDYToSPDYTest.java
@@ -18,9 +18,6 @@
package org.eclipse.jetty.spdy.server.proxy;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-
import java.io.ByteArrayOutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
@@ -52,6 +49,7 @@ import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
+import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.Promise;
@@ -61,35 +59,24 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
@RunWith(value = Parameterized.class)
-public class ProxySPDYToSPDYTest
+public abstract class ProxySPDYToSPDYTest
{
- @Rule
- public final TestWatcher testName = new TestWatcher()
- {
-
- @Override
- public void starting(Description description)
- {
- super.starting(description);
- System.err.printf("Running %s.%s()%n",
- description.getClassName(),
- description.getMethodName());
- }
- };
- private final short version;
-
@Parameterized.Parameters
public static Collection<Short[]> parameters()
{
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
}
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ private final short version;
private SPDYClient.Factory factory;
private Server server;
private Server proxy;
diff --git a/jetty-spdy/spdy-npn-tests/pom.xml b/jetty-spdy/spdy-npn-tests/pom.xml
new file mode 100644
index 0000000000..316d5f3788
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.eclipse.jetty.spdy</groupId>
+ <artifactId>spdy-parent</artifactId>
+ <version>9.1.4-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>spdy-npn-tests</artifactId>
+ <name>Jetty :: SPDY :: NPN Tests</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.mortbay.jetty.npn</groupId>
+ <artifactId>npn-boot</artifactId>
+ <version>${npn.version}</version>
+ <type>jar</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}/npn</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty.npn</groupId>
+ <artifactId>npn-api</artifactId>
+ <version>${npn.api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-start</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.spdy</groupId>
+ <artifactId>spdy-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.spdy</groupId>
+ <artifactId>spdy-http-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.spdy</groupId>
+ <artifactId>spdy-http-server</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java
new file mode 100644
index 0000000000..8ed4803102
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/AbstractNPNTest.java
@@ -0,0 +1,77 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server;
+
+import java.net.InetSocketAddress;
+
+import org.eclipse.jetty.npn.NextProtoNego;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.spdy.client.SPDYClient;
+import org.eclipse.jetty.toolchain.test.TestTracker;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.junit.After;
+import org.junit.Rule;
+
+public class AbstractNPNTest
+{
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ protected Server server;
+ protected SPDYServerConnector connector;
+ protected SPDYClient.Factory clientFactory;
+
+ protected InetSocketAddress prepare() throws Exception
+ {
+ server = new Server();
+ connector = new SPDYServerConnector(server, newSslContextFactory(), null);
+ connector.setPort(0);
+ connector.setIdleTimeout(30000);
+ server.addConnector(connector);
+ server.start();
+
+ QueuedThreadPool threadPool = new QueuedThreadPool();
+ threadPool.setName(threadPool.getName() + "-client");
+ clientFactory = new SPDYClient.Factory(threadPool);
+ clientFactory.start();
+
+ NextProtoNego.debug = true;
+
+ return new InetSocketAddress("localhost", connector.getLocalPort());
+ }
+
+ protected SslContextFactory newSslContextFactory()
+ {
+ SslContextFactory sslContextFactory = new SslContextFactory();
+ sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
+ sslContextFactory.setKeyStorePassword("storepwd");
+ sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
+ sslContextFactory.setTrustStorePassword("storepwd");
+ sslContextFactory.setProtocol("TLSv1");
+ sslContextFactory.setIncludeProtocols("TLSv1");
+ return sslContextFactory;
+ }
+
+ @After
+ public void dispose() throws Exception
+ {
+ clientFactory.stop();
+ server.stop();
+ }
+}
diff --git a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/NpnModuleTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java
index ce48352c3b..c39d1aa58d 100644
--- a/jetty-spdy/spdy-http-server/src/test/java/org/eclipse/jetty/spdy/server/NpnModuleTest.java
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNModuleTest.java
@@ -18,9 +18,6 @@
package org.eclipse.jetty.spdy.server;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -45,8 +42,14 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
@RunWith(Parameterized.class)
-public class NpnModuleTest
+public class NPNModuleTest
{
/** This is here to prevent pointless download attempts */
private static final List<String> KNOWN_GOOD_NPN_URLS = new ArrayList<>();
@@ -66,7 +69,7 @@ public class NpnModuleTest
@Parameters(name = "{index}: mod:{0}")
public static List<Object[]> data()
{
- File npnBootModDir = MavenTestingUtils.getProjectDir("src/main/config/modules/npn");
+ File npnBootModDir = MavenTestingUtils.getProjectDir("../spdy-http-server/src/main/config/modules/npn");
List<Object[]> data = new ArrayList<>();
for (File file : npnBootModDir.listFiles())
{
@@ -86,8 +89,8 @@ public class NpnModuleTest
@BeforeClass
public static void initBaseHome()
{
- File homeDir = MavenTestingUtils.getProjectDir("src/main/config");
- File baseDir = MavenTestingUtils.getTargetTestingDir(NpnModuleTest.class.getName());
+ File homeDir = MavenTestingUtils.getProjectDir("../spdy-http-server/src/main/config");
+ File baseDir = MavenTestingUtils.getTargetTestingDir(NPNModuleTest.class.getName());
FS.ensureEmpty(baseDir);
basehome = new BaseHome(homeDir,baseDir);
}
@@ -139,7 +142,7 @@ public class NpnModuleTest
public static void main(String[] args)
{
- File outputDir = MavenTestingUtils.getTargetTestingDir(NpnModuleTest.class.getSimpleName() + "-main");
+ File outputDir = MavenTestingUtils.getTargetTestingDir(NPNModuleTest.class.getSimpleName() + "-main");
FS.ensureEmpty(outputDir);
for (String ref : KNOWN_GOOD_NPN_URLS)
{
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java
new file mode 100644
index 0000000000..b8f2f10b86
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/NPNNegotiationTest.java
@@ -0,0 +1,207 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.npn.NextProtoNego;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class NPNNegotiationTest extends AbstractNPNTest
+{
+ @Test
+ public void testServerAdvertisingHTTPSpeaksHTTP() throws Exception
+ {
+ InetSocketAddress address = prepare();
+ connector.addConnectionFactory(new HttpConnectionFactory());
+
+ SslContextFactory sslContextFactory = newSslContextFactory();
+ sslContextFactory.start();
+ SSLContext sslContext = sslContextFactory.getSslContext();
+
+ try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
+ {
+ client.setUseClientMode(true);
+ client.setSoTimeout(5000);
+
+ NextProtoNego.put(client, new NextProtoNego.ClientProvider()
+ {
+ @Override
+ public boolean supports()
+ {
+ return true;
+ }
+
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public String selectProtocol(List<String> strings)
+ {
+ Assert.assertNotNull(strings);
+ String protocol = "http/1.1";
+ Assert.assertTrue(strings.contains(protocol));
+ return protocol;
+ }
+ });
+
+ client.startHandshake();
+
+ // Verify that the server really speaks http/1.1
+
+ OutputStream output = client.getOutputStream();
+ output.write(("" +
+ "GET / HTTP/1.1\r\n" +
+ "Host: localhost:" + address.getPort() + "\r\n" +
+ "\r\n" +
+ "").getBytes(StandardCharsets.UTF_8));
+ output.flush();
+
+ InputStream input = client.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
+ String line = reader.readLine();
+ Assert.assertTrue(line.contains(" 404 "));
+ }
+ }
+
+ @Test
+ public void testServerAdvertisingSPDYAndHTTPSpeaksHTTPWhenNegotiated() throws Exception
+ {
+ InetSocketAddress address = prepare();
+ connector.addConnectionFactory(new HttpConnectionFactory());
+
+ SslContextFactory sslContextFactory = newSslContextFactory();
+ sslContextFactory.start();
+ SSLContext sslContext = sslContextFactory.getSslContext();
+ try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
+ {
+ client.setUseClientMode(true);
+ client.setSoTimeout(5000);
+
+ NextProtoNego.put(client, new NextProtoNego.ClientProvider()
+ {
+ @Override
+ public boolean supports()
+ {
+ return true;
+ }
+
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public String selectProtocol(List<String> strings)
+ {
+ Assert.assertNotNull(strings);
+ String spdyProtocol = "spdy/2";
+ Assert.assertTrue(strings.contains(spdyProtocol));
+ String httpProtocol = "http/1.1";
+ Assert.assertTrue(strings.contains(httpProtocol));
+ Assert.assertTrue(strings.indexOf(spdyProtocol) < strings.indexOf(httpProtocol));
+ return httpProtocol;
+ }
+ });
+
+ client.startHandshake();
+
+ // Verify that the server really speaks http/1.1
+
+ OutputStream output = client.getOutputStream();
+ output.write(("" +
+ "GET / HTTP/1.1\r\n" +
+ "Host: localhost:" + address.getPort() + "\r\n" +
+ "\r\n" +
+ "").getBytes(StandardCharsets.UTF_8));
+ output.flush();
+
+ InputStream input = client.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
+ String line = reader.readLine();
+ Assert.assertTrue(line.contains(" 404 "));
+ }
+ }
+
+ @Test
+ public void testServerAdvertisingSPDYAndHTTPSpeaksDefaultProtocolWhenNPNMissing() throws Exception
+ {
+ InetSocketAddress address = prepare();
+ connector.addConnectionFactory(new HttpConnectionFactory());
+
+ SslContextFactory sslContextFactory = newSslContextFactory();
+ sslContextFactory.start();
+ SSLContext sslContext = sslContextFactory.getSslContext();
+ try (SSLSocket client = (SSLSocket)sslContext.getSocketFactory().createSocket(address.getAddress(), address.getPort()))
+ {
+ client.setUseClientMode(true);
+ client.setSoTimeout(5000);
+
+ NextProtoNego.put(client, new NextProtoNego.ClientProvider()
+ {
+ @Override
+ public boolean supports()
+ {
+ return false;
+ }
+
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public String selectProtocol(List<String> strings)
+ {
+ return null;
+ }
+ });
+
+ client.startHandshake();
+
+ // Verify that the server really speaks http/1.1
+
+ OutputStream output = client.getOutputStream();
+ output.write(("" +
+ "GET / HTTP/1.1\r\n" +
+ "Host: localhost:" + address.getPort() + "\r\n" +
+ "\r\n" +
+ "").getBytes(StandardCharsets.UTF_8));
+ output.flush();
+
+ InputStream input = client.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
+ String line = reader.readLine();
+ Assert.assertTrue(line.contains(" 404 "));
+ }
+ }
+}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java
index c69ba17b8c..4ce1689ea1 100644
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLEngineLeakTest.java
@@ -19,39 +19,20 @@
package org.eclipse.jetty.spdy.server;
import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
import java.util.Map;
-import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.spdy.api.GoAwayInfo;
+import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.Session;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
-public class SSLEngineLeakTest extends AbstractTest
+public class SSLEngineLeakTest extends AbstractNPNTest
{
- @Override
- protected SPDYServerConnector newSPDYServerConnector(Server server, ServerSessionFrameListener listener)
- {
- SslContextFactory sslContextFactory = newSslContextFactory();
- return new SPDYServerConnector(server, sslContextFactory, listener);
- }
-
- @Override
- protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool)
- {
- SslContextFactory sslContextFactory = newSslContextFactory();
- return new SPDYClient.Factory(threadPool, null, sslContextFactory);
- }
-
@Test
- @Ignore
public void testSSLEngineLeak() throws Exception
{
System.gc();
@@ -67,12 +48,12 @@ public class SSLEngineLeakTest extends AbstractTest
// Allow the close to arrive to the server and the selector to process it
Thread.sleep(1000);
- // Perform GC to be sure that the WeakHashMap is cleared
- Thread.sleep(1000);
+ // Perform GC to be sure that the map is cleared
System.gc();
+ Thread.sleep(1000);
- // Check that the WeakHashMap is empty
- if (objects.size()!=initialSize)
+ // Check that the map is empty
+ if (objects.size() != initialSize)
{
System.err.println(objects);
server.dumpStdErr();
@@ -83,7 +64,8 @@ public class SSLEngineLeakTest extends AbstractTest
private void avoidStackLocalVariables() throws Exception
{
- Session session = startClient(startServer(null), null);
+ InetSocketAddress address = prepare();
+ Session session = clientFactory.newSPDYClient(SPDY.V3).connect(address, null);
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
}
}
diff --git a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java
index 267d8593b6..a6649eb746 100644
--- a/jetty-spdy/spdy-server/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/SSLSynReplyTest.java
@@ -23,48 +23,20 @@ import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.List;
-import java.util.concurrent.Executor;
-
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
-import org.eclipse.jetty.spdy.client.SPDYClient;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.Test;
-public class SSLSynReplyTest extends SynReplyTest
+public class SSLSynReplyTest extends AbstractNPNTest
{
- @Override
- protected SPDYServerConnector newSPDYServerConnector(Server server, ServerSessionFrameListener listener)
- {
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.setEndpointIdentificationAlgorithm("");
- return new SPDYServerConnector(server, sslContextFactory, listener);
- }
-
- @Override
- protected SPDYClient.Factory newSPDYClientFactory(Executor threadPool)
- {
- SslContextFactory sslContextFactory = newSslContextFactory();
- sslContextFactory.setEndpointIdentificationAlgorithm("");
- return new SPDYClient.Factory(threadPool, null, sslContextFactory);
- }
-
- @Before
- public void init()
- {
- NextProtoNego.debug = true;
- }
-
@Test
public void testGentleCloseDuringHandshake() throws Exception
{
- InetSocketAddress address = startServer(version, null);
+ InetSocketAddress address = prepare();
SslContextFactory sslContextFactory = newSslContextFactory();
sslContextFactory.start();
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
@@ -124,7 +96,7 @@ public class SSLSynReplyTest extends SynReplyTest
@Test
public void testAbruptCloseDuringHandshake() throws Exception
{
- InetSocketAddress address = startServer(version, null);
+ InetSocketAddress address = prepare();
SslContextFactory sslContextFactory = newSslContextFactory();
sslContextFactory.start();
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java
new file mode 100644
index 0000000000..355c597744
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPLoadTest.java
@@ -0,0 +1,29 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server.proxy;
+
+import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
+
+public class NPNProxySPDYToHTTPLoadTest extends ProxySPDYToHTTPLoadTest
+{
+ public NPNProxySPDYToHTTPLoadTest(short version)
+ {
+ super(version, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
+ }
+}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java
new file mode 100644
index 0000000000..8fbcf480ed
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToHTTPTest.java
@@ -0,0 +1,27 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server.proxy;
+
+public class NPNProxySPDYToHTTPTest extends ProxySPDYToHTTPTest
+{
+ public NPNProxySPDYToHTTPTest(short version)
+ {
+ super(version);
+ }
+}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java
new file mode 100644
index 0000000000..2e837be2b0
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYLoadTest.java
@@ -0,0 +1,27 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server.proxy;
+
+public class NPNProxySPDYToSPDYLoadTest extends ProxySPDYToSPDYLoadTest
+{
+ public NPNProxySPDYToSPDYLoadTest(short version)
+ {
+ super(version);
+ }
+}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java
new file mode 100644
index 0000000000..08b3bfaa32
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/java/org/eclipse/jetty/spdy/server/proxy/NPNProxySPDYToSPDYTest.java
@@ -0,0 +1,27 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server.proxy;
+
+public class NPNProxySPDYToSPDYTest extends ProxySPDYToSPDYTest
+{
+ public NPNProxySPDYToSPDYTest(short version)
+ {
+ super(version);
+ }
+}
diff --git a/jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties b/jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..ead13ec197
--- /dev/null
+++ b/jetty-spdy/spdy-npn-tests/src/test/resources/jetty-logging.properties
@@ -0,0 +1,2 @@
+org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
+#org.eclipse.jetty.spdy.LEVEL=DEBUG
diff --git a/jetty-spdy/spdy-server/src/test/resources/keystore.jks b/jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jks
index 428ba54776..428ba54776 100644
--- a/jetty-spdy/spdy-server/src/test/resources/keystore.jks
+++ b/jetty-spdy/spdy-npn-tests/src/test/resources/keystore.jks
Binary files differ
diff --git a/jetty-spdy/spdy-server/src/test/resources/truststore.jks b/jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jks
index 839cb8c351..839cb8c351 100644
--- a/jetty-spdy/spdy-server/src/test/resources/truststore.jks
+++ b/jetty-spdy/spdy-npn-tests/src/test/resources/truststore.jks
Binary files differ
diff --git a/jetty-spdy/spdy-server/pom.xml b/jetty-spdy/spdy-server/pom.xml
index 298cd8c2ae..3b45def038 100644
--- a/jetty-spdy/spdy-server/pom.xml
+++ b/jetty-spdy/spdy-server/pom.xml
@@ -18,36 +18,6 @@
<build>
<plugins>
<plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>copy</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.mortbay.jetty.npn</groupId>
- <artifactId>npn-boot</artifactId>
- <version>${npn.version}</version>
- <type>jar</type>
- <overWrite>false</overWrite>
- <outputDirectory>${project.build.directory}/npn</outputDirectory>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
- </configuration>
- </plugin>
- <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java
index b06bf0d75e..b58a01e219 100644
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java
+++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnection.java
@@ -18,146 +18,49 @@
package org.eclipse.jetty.spdy.server;
-import java.io.IOException;
import java.util.List;
-
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLEngineResult;
-import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-public class NPNServerConnection extends AbstractConnection implements NextProtoNego.ServerProvider
+public class NPNServerConnection extends NegotiatingServerConnection implements NextProtoNego.ServerProvider
{
- private final Logger LOG = Log.getLogger(getClass());
- private final Connector connector;
- private final SSLEngine engine;
- private final List<String> protocols;
- private final String defaultProtocol;
- private String nextProtocol; // No need to be volatile: it is modified and read by the same thread
+ private static final Logger LOG = Log.getLogger(NPNServerConnection.class);
public NPNServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, List<String> protocols, String defaultProtocol)
{
- super(endPoint, connector.getExecutor());
- this.connector = connector;
- this.protocols = protocols;
- this.defaultProtocol = defaultProtocol;
- this.engine = engine;
+ super(connector, endPoint, engine, protocols, defaultProtocol);
NextProtoNego.put(engine, this);
}
@Override
- public void onOpen()
- {
- super.onOpen();
- fillInterested();
- }
-
- @Override
- public void onFillable()
- {
- int filled = fill();
-
- if (filled == 0)
- {
- if (nextProtocol == null)
- {
- if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
- {
- // Here the SSL handshake is finished, but while the client sent
- // the NPN extension, the server application did not select the
- // protocol; we need to close as the protocol cannot be negotiated.
- LOG.debug("{} missing next protocol. SSLEngine: {}", this, engine);
- close();
- }
- else
- {
- // Here the SSL handshake is not finished yet but we filled 0 bytes,
- // so we need to read more.
- fillInterested();
- }
- }
- else
- {
- ConnectionFactory connectionFactory = connector.getConnectionFactory(nextProtocol);
- if (connectionFactory == null)
- {
- LOG.debug("{} application selected protocol '{}', but no correspondent {} has been configured",
- this, nextProtocol, ConnectionFactory.class.getName());
- close();
- }
- else
- {
- EndPoint endPoint = getEndPoint();
- Connection oldConnection = endPoint.getConnection();
- Connection newConnection = connectionFactory.newConnection(connector, endPoint);
- LOG.debug("{} switching from {} to {}", this, oldConnection, newConnection);
- oldConnection.onClose();
- endPoint.setConnection(newConnection);
- getEndPoint().getConnection().onOpen();
- }
- }
- }
- else if (filled < 0)
- {
- // Something went bad, we need to close.
- LOG.debug("{} closing on client close", this);
- close();
- }
- else
- {
- // Must never happen, since we fill using an empty buffer
- throw new IllegalStateException();
- }
- }
-
- private int fill()
- {
- try
- {
- return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
- }
- catch (IOException x)
- {
- LOG.debug(x);
- close();
- return -1;
- }
- }
-
- @Override
public void unsupported()
{
- protocolSelected(defaultProtocol);
+ protocolSelected(getDefaultProtocol());
}
@Override
public List<String> protocols()
{
- return protocols;
+ return getProtocols();
}
@Override
public void protocolSelected(String protocol)
{
LOG.debug("{} protocol selected {}", this, protocol);
- nextProtocol = protocol != null ? protocol : defaultProtocol;
- NextProtoNego.remove(engine);
+ setProtocol(protocol != null ? protocol : getDefaultProtocol());
+ NextProtoNego.remove(getSSLEngine());
}
@Override
public void close()
{
- NextProtoNego.remove(engine);
- EndPoint endPoint = getEndPoint();
- endPoint.shutdownOutput();
- endPoint.close();
+ NextProtoNego.remove(getSSLEngine());
+ super.close();
}
}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java
index db18ef2f40..f0e9e01896 100644
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java
+++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NPNServerConnectionFactory.java
@@ -16,106 +16,45 @@
// ========================================================================
//
-
package org.eclipse.jetty.spdy.server;
-import java.util.Arrays;
-import java.util.Iterator;
import java.util.List;
-
import javax.net.ssl.SSLEngine;
-import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.npn.NextProtoNego;
-import org.eclipse.jetty.server.AbstractConnectionFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
-public class NPNServerConnectionFactory extends AbstractConnectionFactory
+public class NPNServerConnectionFactory extends NegotiatingServerConnectionFactory
{
private static final Logger LOG = Log.getLogger(NPNServerConnectionFactory.class);
- private final List<String> _protocols;
- private String _defaultProtocol;
- /* ------------------------------------------------------------ */
- /**
- * @param protocols List of supported protocols in priority order
- */
- public NPNServerConnectionFactory(@Name("protocols")String... protocols)
+ public NPNServerConnectionFactory(@Name("protocols") String... protocols)
{
- super("npn");
- _protocols=Arrays.asList(protocols);
-
+ super("npn", protocols);
try
{
- if (NextProtoNego.class.getClassLoader()!=null)
- {
- LOG.warn("NextProtoNego not from bootloader classloader: "+NextProtoNego.class.getClassLoader());
- throw new IllegalStateException("NextProtoNego not on bootloader");
- }
- }
- catch(Throwable th)
- {
- LOG.warn("NextProtoNego not available: "+th);
- throw new IllegalStateException("NextProtoNego not available",th);
- }
- }
-
- public String getDefaultProtocol()
- {
- return _defaultProtocol;
- }
-
- public void setDefaultProtocol(String defaultProtocol)
- {
- _defaultProtocol = defaultProtocol;
- }
-
- public List<String> getProtocols()
- {
- return _protocols;
- }
-
- @Override
- public Connection newConnection(Connector connector, EndPoint endPoint)
- {
- List<String> protocols=_protocols;
- if (protocols==null || protocols.size()==0)
- {
- protocols=connector.getProtocols();
- for (Iterator<String> i=protocols.iterator();i.hasNext();)
+ ClassLoader npnClassLoader = NextProtoNego.class.getClassLoader();
+ if (npnClassLoader != null)
{
- String protocol=i.next();
- if (protocol.startsWith("SSL-")||protocol.equals("NPN"))
- i.remove();
+ LOG.warn("NPN must be in the boot classloader, not in: " + npnClassLoader);
+ throw new IllegalStateException("NPN must be in the boot classloader");
}
}
-
- String dft=_defaultProtocol;
- if (dft==null)
- dft=_protocols.get(0);
-
- SSLEngine engine=null;
- EndPoint ep=endPoint;
- while(engine==null && ep!=null)
+ catch (Throwable x)
{
- // TODO make more generic
- if (ep instanceof SslConnection.DecryptedEndPoint)
- engine=((SslConnection.DecryptedEndPoint)ep).getSslConnection().getSSLEngine();
- else
- ep=null;
+ LOG.warn("NPN not available: " + x);
+ throw new IllegalStateException("NPN not available", x);
}
-
- return configure(new NPNServerConnection(endPoint, engine, connector,protocols,_defaultProtocol),connector,endPoint);
}
@Override
- public String toString()
+ protected AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
{
- return String.format("%s@%x{%s,%s,%s}",this.getClass().getSimpleName(),hashCode(),getProtocol(),getDefaultProtocol(),getProtocols());
+ return new NPNServerConnection(endPoint, engine, connector, protocols, defaultProtocol);
}
}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnection.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnection.java
new file mode 100644
index 0000000000..b1fb87eb5e
--- /dev/null
+++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnection.java
@@ -0,0 +1,163 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server;
+
+import java.io.IOException;
+import java.util.List;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.server.ConnectionFactory;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+public abstract class NegotiatingServerConnection extends AbstractConnection
+{
+ private static final Logger LOG = Log.getLogger(NegotiatingServerConnection.class);
+
+ private final Connector connector;
+ private final SSLEngine engine;
+ private final List<String> protocols;
+ private final String defaultProtocol;
+ private String protocol; // No need to be volatile: it is modified and read by the same thread
+
+ protected NegotiatingServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
+ {
+ super(endPoint, connector.getExecutor());
+ this.connector = connector;
+ this.protocols = protocols;
+ this.defaultProtocol = defaultProtocol;
+ this.engine = engine;
+ }
+
+ protected List<String> getProtocols()
+ {
+ return protocols;
+ }
+
+ protected String getDefaultProtocol()
+ {
+ return defaultProtocol;
+ }
+
+ protected SSLEngine getSSLEngine()
+ {
+ return engine;
+ }
+
+ protected String getProtocol()
+ {
+ return protocol;
+ }
+
+ protected void setProtocol(String protocol)
+ {
+ this.protocol = protocol;
+ }
+
+ @Override
+ public void onOpen()
+ {
+ super.onOpen();
+ fillInterested();
+ }
+
+ @Override
+ public void onFillable()
+ {
+ int filled = fill();
+
+ if (filled == 0)
+ {
+ if (protocol == null)
+ {
+ if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
+ {
+ // Here the SSL handshake is finished, but the protocol has not been negotiated.
+ LOG.debug("{} could not negotiate protocol, SSLEngine: {}", this, engine);
+ close();
+ }
+ else
+ {
+ // Here the SSL handshake is not finished yet but we filled 0 bytes,
+ // so we need to read more.
+ fillInterested();
+ }
+ }
+ else
+ {
+ ConnectionFactory connectionFactory = connector.getConnectionFactory(protocol);
+ if (connectionFactory == null)
+ {
+ LOG.debug("{} application selected protocol '{}', but no correspondent {} has been configured",
+ this, protocol, ConnectionFactory.class.getName());
+ close();
+ }
+ else
+ {
+ EndPoint endPoint = getEndPoint();
+ Connection oldConnection = endPoint.getConnection();
+ Connection newConnection = connectionFactory.newConnection(connector, endPoint);
+ LOG.debug("{} switching from {} to {}", this, oldConnection, newConnection);
+ oldConnection.onClose();
+ endPoint.setConnection(newConnection);
+ getEndPoint().getConnection().onOpen();
+ }
+ }
+ }
+ else if (filled < 0)
+ {
+ // Something went bad, we need to close.
+ LOG.debug("{} closing on client close", this);
+ close();
+ }
+ else
+ {
+ // Must never happen, since we fill using an empty buffer
+ throw new IllegalStateException();
+ }
+ }
+
+ private int fill()
+ {
+ try
+ {
+ return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
+ }
+ catch (IOException x)
+ {
+ LOG.debug(x);
+ close();
+ return -1;
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ // Gentler close for SSL.
+ getEndPoint().shutdownOutput();
+ super.close();
+ }
+}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnectionFactory.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnectionFactory.java
new file mode 100644
index 0000000000..4ec3e9104b
--- /dev/null
+++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/NegotiatingServerConnectionFactory.java
@@ -0,0 +1,103 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+//
+
+package org.eclipse.jetty.spdy.server;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import javax.net.ssl.SSLEngine;
+
+import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.ssl.SslConnection;
+import org.eclipse.jetty.server.AbstractConnectionFactory;
+import org.eclipse.jetty.server.Connector;
+
+public abstract class NegotiatingServerConnectionFactory extends AbstractConnectionFactory
+{
+ private final List<String> protocols;
+ private String defaultProtocol;
+
+ public NegotiatingServerConnectionFactory(String protocol, String... protocols)
+ {
+ super(protocol);
+ this.protocols = Arrays.asList(protocols);
+ }
+
+ public String getDefaultProtocol()
+ {
+ return defaultProtocol;
+ }
+
+ public void setDefaultProtocol(String defaultProtocol)
+ {
+ this.defaultProtocol = defaultProtocol;
+ }
+
+ public List<String> getProtocols()
+ {
+ return protocols;
+ }
+
+ @Override
+ public Connection newConnection(Connector connector, EndPoint endPoint)
+ {
+ List<String> protocols = this.protocols;
+ if (protocols.isEmpty())
+ {
+ protocols = connector.getProtocols();
+ Iterator<String> i = protocols.iterator();
+ while (i.hasNext())
+ {
+ String protocol = i.next();
+ String prefix = "ssl-";
+ if (protocol.regionMatches(true, 0, prefix, 0, prefix.length()) || protocol.equalsIgnoreCase("alpn"))
+ {
+ i.remove();
+ }
+ }
+ }
+
+ String dft = defaultProtocol;
+ if (dft == null && !protocols.isEmpty())
+ dft = protocols.get(0);
+
+ SSLEngine engine = null;
+ EndPoint ep = endPoint;
+ while (engine == null && ep != null)
+ {
+ // TODO make more generic
+ if (ep instanceof SslConnection.DecryptedEndPoint)
+ engine = ((SslConnection.DecryptedEndPoint)ep).getSslConnection().getSSLEngine();
+ else
+ ep = null;
+ }
+
+ return configure(newServerConnection(connector, endPoint, engine, protocols, dft), connector, endPoint);
+ }
+
+ protected abstract AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol);
+
+ @Override
+ public String toString()
+ {
+ return String.format("%s@%x{%s,%s,%s}", getClass().getSimpleName(), hashCode(), getProtocol(), getDefaultProtocol(), getProtocols());
+ }
+}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java
index 36eaec1a0a..d6a2a7b92b 100644
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java
+++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnectionFactory.java
@@ -47,19 +47,34 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
@ManagedObject("SPDY Server Connection Factory")
public class SPDYServerConnectionFactory extends AbstractConnectionFactory
{
- // This method is placed here so as to provide a check for NPN before attempting to load any
- // NPN classes.
+ /**
+ * @deprecated use {@link #checkProtocolNegotiationAvailable()} instead.
+ */
+ @Deprecated
public static void checkNPNAvailable()
{
+ checkProtocolNegotiationAvailable();
+ }
+
+ public static void checkProtocolNegotiationAvailable()
+ {
+ if (!isAvailableInBootClassPath("org.eclipse.jetty.alpn.ALPN") &&
+ !isAvailableInBootClassPath("org.eclipse.jetty.npn.NextProtoNego"))
+ throw new IllegalStateException("No ALPN nor NPN classes available");
+ }
+
+ private static boolean isAvailableInBootClassPath(String className)
+ {
try
{
- Class<?> npn = ClassLoader.getSystemClassLoader().loadClass("org.eclipse.jetty.npn.NextProtoNego");
- if (npn.getClassLoader() != null)
- throw new IllegalStateException("NextProtoNego must be on JVM boot path");
+ Class<?> klass = ClassLoader.getSystemClassLoader().loadClass(className);
+ if (klass.getClassLoader() != null)
+ throw new IllegalStateException(className + " must be on JVM boot classpath");
+ return true;
}
- catch (ClassNotFoundException e)
+ catch (ClassNotFoundException x)
{
- throw new IllegalStateException("No NextProtoNego on boot path", e);
+ return false;
}
}
diff --git a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java
index f65635f8ec..35dd6ff148 100644
--- a/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java
+++ b/jetty-spdy/spdy-server/src/main/java/org/eclipse/jetty/spdy/server/SPDYServerConnector.java
@@ -18,7 +18,8 @@
package org.eclipse.jetty.spdy.server;
-import org.eclipse.jetty.server.ConnectionFactory;
+import java.util.Objects;
+
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -30,23 +31,21 @@ public class SPDYServerConnector extends ServerConnector
{
public SPDYServerConnector(Server server, ServerSessionFrameListener listener)
{
- this(server, null, listener);
+ super(server, (SslContextFactory)null, new SPDYServerConnectionFactory(SPDY.V2, listener));
}
public SPDYServerConnector(Server server, SslContextFactory sslContextFactory, ServerSessionFrameListener listener)
{
- super(server,
- sslContextFactory,
- sslContextFactory==null
- ?new ConnectionFactory[]{new SPDYServerConnectionFactory(SPDY.V2, listener)}
- :new ConnectionFactory[]{
- new NPNServerConnectionFactory("spdy/3","spdy/2","http/1.1"),
- new HttpConnectionFactory(),
- new SPDYServerConnectionFactory(SPDY.V2, listener),
- new SPDYServerConnectionFactory(SPDY.V3, listener)});
- if (getConnectionFactory(NPNServerConnectionFactory.class)!=null)
- getConnectionFactory(NPNServerConnectionFactory.class).setDefaultProtocol("http/1.1");
-
+ this(server, sslContextFactory, listener, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
}
+ public SPDYServerConnector(Server server, SslContextFactory sslContextFactory, ServerSessionFrameListener listener, NegotiatingServerConnectionFactory negotiator)
+ {
+ super(server, Objects.requireNonNull(sslContextFactory),
+ negotiator,
+ new SPDYServerConnectionFactory(SPDY.V3, listener),
+ new SPDYServerConnectionFactory(SPDY.V2, listener),
+ new HttpConnectionFactory());
+ negotiator.setDefaultProtocol("http/1.1");
+ }
}
diff --git a/pom.xml b/pom.xml
index fd7ddc0666..4393f45f74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -814,137 +814,137 @@
</build>
</profile>
<profile>
- <id>7u9</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_9</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.3.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u10</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_10</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.3.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u11</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_11</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.3.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u13</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_13</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.4.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u15</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_15</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.5.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u17</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_17</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.5.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u21</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_21</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.5.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u25</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_25</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.5.v20130313</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u40</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_40</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.6.v20130911</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u45</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_45</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.6.v20130911</npn.version>
- </properties>
- </profile>
- <profile>
- <id>7u51</id>
- <activation>
- <property>
- <name>java.version</name>
- <value>1.7.0_51</value>
- </property>
- </activation>
- <properties>
- <npn.version>1.1.6.v20130911</npn.version>
- </properties>
- </profile>
+ <id>7u9</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_9</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.3.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u10</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_10</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.3.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u11</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_11</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.3.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u13</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_13</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.4.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u15</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_15</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.5.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u17</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_17</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.5.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u21</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_21</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.5.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u25</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_25</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.5.v20130313</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u40</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_40</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.6.v20130911</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u45</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_45</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.6.v20130911</npn.version>
+ </properties>
+ </profile>
+ <profile>
+ <id>7u51</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ <value>1.7.0_51</value>
+ </property>
+ </activation>
+ <properties>
+ <npn.version>1.1.6.v20130911</npn.version>
+ </properties>
+ </profile>
</profiles>
</project>
diff --git a/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java b/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java
index c8b9814d21..b1be102f65 100644
--- a/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java
+++ b/tests/test-webapps/test-proxy-webapp/src/test/java/org/eclipse/jetty/TestTransparentProxyServer.java
@@ -102,7 +102,7 @@ public class TestTransparentProxyServer
// Spdy Connector
- SPDYServerConnectionFactory.checkNPNAvailable();
+ SPDYServerConnectionFactory.checkProtocolNegotiationAvailable();
PushStrategy push = new ReferrerPushStrategy();
HTTPSPDYServerConnectionFactory spdy2 = new HTTPSPDYServerConnectionFactory(2,config,push);
spdy2.setInputBufferSize(8192);

Back to the top