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.
This commit is contained in:
parent
48c803b693
commit
b994db698c
|
@ -72,7 +72,7 @@ public class SpdyConnector
|
||||||
new HTTPSPDYServerConnectionFactory(3,https_config,new ReferrerPushStrategy());
|
new HTTPSPDYServerConnectionFactory(3,https_config,new ReferrerPushStrategy());
|
||||||
|
|
||||||
// NPN Factory
|
// NPN Factory
|
||||||
SPDYServerConnectionFactory.checkNPNAvailable();
|
SPDYServerConnectionFactory.checkProtocolNegotiationAvailable();
|
||||||
NPNServerConnectionFactory npn =
|
NPNServerConnectionFactory npn =
|
||||||
new NPNServerConnectionFactory(spdy3.getProtocol(),spdy2.getProtocol(),http.getDefaultProtocol());
|
new NPNServerConnectionFactory(spdy3.getProtocol(),spdy2.getProtocol(),http.getDefaultProtocol());
|
||||||
npn.setDefaultProtocol(http.getDefaultProtocol());
|
npn.setDefaultProtocol(http.getDefaultProtocol());
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class SpdyServer
|
||||||
// Spdy Connector
|
// Spdy Connector
|
||||||
|
|
||||||
// Make sure that the required NPN implementations are available.
|
// Make sure that the required NPN implementations are available.
|
||||||
SPDYServerConnectionFactory.checkNPNAvailable();
|
SPDYServerConnectionFactory.checkProtocolNegotiationAvailable();
|
||||||
|
|
||||||
// A ReferrerPushStrategy is being initialized.
|
// A ReferrerPushStrategy is being initialized.
|
||||||
// See: http://www.eclipse.org/jetty/documentation/current/spdy-configuring-push.html for more details.
|
// See: http://www.eclipse.org/jetty/documentation/current/spdy-configuring-push.html for more details.
|
||||||
|
|
|
@ -23,13 +23,17 @@
|
||||||
<module>spdy-example-webapp</module>
|
<module>spdy-example-webapp</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<profiles>
|
||||||
<dependency>
|
<profile>
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
<id>jdk7-npn</id>
|
||||||
<artifactId>jetty-test-helper</artifactId>
|
<activation>
|
||||||
<scope>test</scope>
|
<jdk>[1.7,1.8)</jdk>
|
||||||
</dependency>
|
</activation>
|
||||||
</dependencies>
|
<modules>
|
||||||
|
<module>spdy-npn-tests</module>
|
||||||
|
</modules>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -70,4 +74,12 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||||
|
<artifactId>jetty-test-helper</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -17,36 +17,6 @@
|
||||||
<url>http://www.eclipse.org/jetty</url>
|
<url>http://www.eclipse.org/jetty</url>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<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>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -18,87 +18,28 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.client;
|
package org.eclipse.jetty.spdy.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.AbstractConnection;
|
|
||||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||||
import org.eclipse.jetty.io.Connection;
|
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.RuntimeIOException;
|
|
||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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 static final Logger LOG = Log.getLogger(NPNClientConnection.class);
|
||||||
private final SPDYClient client;
|
|
||||||
private final ClientConnectionFactory connectionFactory;
|
|
||||||
private final SSLEngine engine;
|
|
||||||
private final Map<String, Object> context;
|
|
||||||
private volatile boolean completed;
|
|
||||||
|
|
||||||
public NPNClientConnection(EndPoint endPoint, SPDYClient client, ClientConnectionFactory connectionFactory, SSLEngine sslEngine, Map<String, Object> context)
|
private final String protocol;
|
||||||
{
|
|
||||||
super(endPoint, client.getFactory().getExecutor());
|
|
||||||
this.client = client;
|
|
||||||
this.connectionFactory = connectionFactory;
|
|
||||||
this.engine = sslEngine;
|
|
||||||
this.context = context;
|
|
||||||
NextProtoNego.put(engine, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public NPNClientConnection(EndPoint endPoint, Executor executor, ClientConnectionFactory connectionFactory, SSLEngine sslEngine, Map<String, Object> context, String protocol)
|
||||||
public void onOpen()
|
|
||||||
{
|
{
|
||||||
super.onOpen();
|
super(endPoint, executor, sslEngine, connectionFactory, context);
|
||||||
try
|
this.protocol = protocol;
|
||||||
{
|
NextProtoNego.put(sslEngine, this);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,31 +51,31 @@ public class NPNClientConnection extends AbstractConnection implements NextProto
|
||||||
@Override
|
@Override
|
||||||
public void unsupported()
|
public void unsupported()
|
||||||
{
|
{
|
||||||
NextProtoNego.remove(engine);
|
NextProtoNego.remove(getSSLEngine());
|
||||||
completed = true;
|
completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String selectProtocol(List<String> protocols)
|
public String selectProtocol(List<String> protocols)
|
||||||
{
|
{
|
||||||
NextProtoNego.remove(engine);
|
if (protocols.contains(protocol))
|
||||||
completed = true;
|
{
|
||||||
return client.selectProtocol(protocols);
|
NextProtoNego.remove(getSSLEngine());
|
||||||
|
completed();
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG.info("Could not negotiate protocol: server {} - client {}", protocols, protocol);
|
||||||
|
close();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceConnection()
|
@Override
|
||||||
|
public void close()
|
||||||
{
|
{
|
||||||
EndPoint endPoint = getEndPoint();
|
NextProtoNego.remove(getSSLEngine());
|
||||||
try
|
super.close();
|
||||||
{
|
|
||||||
Connection oldConnection = endPoint.getConnection();
|
|
||||||
Connection newConnection = connectionFactory.newConnection(endPoint, context);
|
|
||||||
ClientConnectionFactory.Helper.replaceConnection(oldConnection, newConnection);
|
|
||||||
}
|
|
||||||
catch (Throwable x)
|
|
||||||
{
|
|
||||||
LOG.debug(x);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.eclipse.jetty.spdy.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
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.EndPoint;
|
||||||
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
|
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
|
||||||
|
|
||||||
public class NPNClientConnectionFactory implements ClientConnectionFactory
|
public class NPNClientConnectionFactory extends NegotiatingClientConnectionFactory
|
||||||
{
|
{
|
||||||
private final SPDYClient client;
|
private final Executor executor;
|
||||||
private final ClientConnectionFactory connectionFactory;
|
private final String protocol;
|
||||||
|
|
||||||
public NPNClientConnectionFactory(SPDYClient client, ClientConnectionFactory connectionFactory)
|
public NPNClientConnectionFactory(Executor executor, ClientConnectionFactory connectionFactory, String protocol)
|
||||||
{
|
{
|
||||||
this.client = client;
|
super(connectionFactory);
|
||||||
this.connectionFactory = connectionFactory;
|
this.executor = executor;
|
||||||
|
this.protocol = protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
|
public Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
|
||||||
{
|
{
|
||||||
return new NPNClientConnection(endPoint, client, connectionFactory,
|
return new NPNClientConnection(endPoint, executor, getClientConnectionFactory(),
|
||||||
(SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY), context);
|
(SSLEngine)context.get(SslClientConnectionFactory.SSL_ENGINE_CONTEXT_KEY), context, protocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,6 @@ import java.nio.channels.SocketChannel;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
@ -86,10 +85,6 @@ public class SPDYClient
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
setInitialWindowSize(65536);
|
setInitialWindowSize(65536);
|
||||||
setDispatchIO(true);
|
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()
|
public short getVersion()
|
||||||
|
@ -239,17 +234,6 @@ public class SPDYClient
|
||||||
this.connectionFactory = connectionFactory;
|
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()
|
protected FlowControlStrategy newFlowControlStrategy()
|
||||||
{
|
{
|
||||||
return FlowControlStrategyFactory.newFlowControlStrategy(version);
|
return FlowControlStrategyFactory.newFlowControlStrategy(version);
|
||||||
|
@ -357,7 +341,19 @@ public class SPDYClient
|
||||||
|
|
||||||
public SPDYClient newSPDYClient(short version)
|
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
|
@Override
|
||||||
|
|
|
@ -16,36 +16,6 @@
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<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>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -33,35 +33,18 @@
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>copy</id>
|
<id>artifact-jars</id>
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>copy</goal>
|
<goal>jar</goal>
|
||||||
|
<goal>test-jar</goal>
|
||||||
</goals>
|
</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>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<argLine>-Xbootclasspath/p:${project.build.directory}/npn/npn-boot-${npn.version}.jar</argLine>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
@ -127,12 +110,6 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-start</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
|
|
|
@ -19,12 +19,14 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server.proxy;
|
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.HttpConfiguration;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
import org.eclipse.jetty.spdy.api.SPDY;
|
import org.eclipse.jetty.spdy.api.SPDY;
|
||||||
import org.eclipse.jetty.spdy.server.NPNServerConnectionFactory;
|
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.spdy.server.SPDYServerConnectionFactory;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
|
|
||||||
|
@ -37,7 +39,7 @@ public class HTTPSPDYProxyServerConnector extends ServerConnector
|
||||||
|
|
||||||
public HTTPSPDYProxyServerConnector(Server server, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector)
|
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)
|
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)
|
public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector)
|
||||||
{
|
{
|
||||||
super(server,
|
this(server, sslContextFactory, config, proxyEngineSelector, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
|
||||||
sslContextFactory,
|
}
|
||||||
sslContextFactory == null
|
|
||||||
? new ConnectionFactory[]{new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector)}
|
public HTTPSPDYProxyServerConnector(Server server, SslContextFactory sslContextFactory, HttpConfiguration config, ProxyEngineSelector proxyEngineSelector, NegotiatingServerConnectionFactory negotiatingFactory)
|
||||||
: new ConnectionFactory[]{new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"),
|
{
|
||||||
new SPDYServerConnectionFactory(SPDY.V3, proxyEngineSelector),
|
super(server, Objects.requireNonNull(sslContextFactory), negotiatingFactory,
|
||||||
new SPDYServerConnectionFactory(SPDY.V2, proxyEngineSelector),
|
new SPDYServerConnectionFactory(SPDY.V3, proxyEngineSelector),
|
||||||
new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector)});
|
new SPDYServerConnectionFactory(SPDY.V2, proxyEngineSelector),
|
||||||
NPNServerConnectionFactory npnConnectionFactory = getConnectionFactory(NPNServerConnectionFactory.class);
|
new ProxyHTTPConnectionFactory(config, SPDY.V2, proxyEngineSelector));
|
||||||
if (npnConnectionFactory != null)
|
negotiatingFactory.setDefaultProtocol("http/1.1");
|
||||||
npnConnectionFactory.setDefaultProtocol("http/1.1");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,11 +73,6 @@ public abstract class AbstractHTTPSPDYTest
|
||||||
this.version = version;
|
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
|
protected InetSocketAddress startHTTPServer(short version, Handler handler, long idleTimeout) throws Exception
|
||||||
{
|
{
|
||||||
QueuedThreadPool threadPool = new QueuedThreadPool(256);
|
QueuedThreadPool threadPool = new QueuedThreadPool(256);
|
||||||
|
@ -89,7 +84,6 @@ public abstract class AbstractHTTPSPDYTest
|
||||||
server.addConnector(connector);
|
server.addConnector(connector);
|
||||||
server.setHandler(handler);
|
server.setHandler(handler);
|
||||||
server.start();
|
server.start();
|
||||||
server.dumpStdErr();
|
|
||||||
return new InetSocketAddress("localhost", connector.getLocalPort());
|
return new InetSocketAddress("localhost", connector.getLocalPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,13 +98,7 @@ public abstract class AbstractHTTPSPDYTest
|
||||||
HttpConfiguration httpConfiguration = new HttpConfiguration();
|
HttpConfiguration httpConfiguration = new HttpConfiguration();
|
||||||
httpConfiguration.setSendServerVersion(true);
|
httpConfiguration.setSendServerVersion(true);
|
||||||
httpConfiguration.setSendXPoweredBy(true);
|
httpConfiguration.setSendXPoweredBy(true);
|
||||||
HTTPSPDYServerConnector connector = new HTTPSPDYServerConnector(server,version, httpConfiguration, new PushStrategy.None());
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
|
protected Session startClient(short version, InetSocketAddress socketAddress, SessionFrameListener listener) throws Exception
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server.proxy;
|
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.net.InetSocketAddress;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
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.http.HTTPSPDYHeader;
|
||||||
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
|
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
|
||||||
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
|
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.Callback;
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
import org.eclipse.jetty.util.Promise;
|
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.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestWatcher;
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class ProxyHTTPToSPDYTest
|
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
|
@Parameterized.Parameters
|
||||||
public static Collection<Short[]> parameters()
|
public static Collection<Short[]> parameters()
|
||||||
{
|
{
|
||||||
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
|
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 SPDYClient.Factory factory;
|
||||||
private Server server;
|
private Server server;
|
||||||
private Server proxy;
|
private Server proxy;
|
||||||
|
|
|
@ -18,11 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server.proxy;
|
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.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
@ -38,13 +33,13 @@ import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
|
import org.eclipse.jetty.server.HttpConfiguration;
|
||||||
import org.eclipse.jetty.server.Request;
|
import org.eclipse.jetty.server.Request;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
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.StringDataInfo;
|
||||||
import org.eclipse.jetty.spdy.api.SynInfo;
|
import org.eclipse.jetty.spdy.api.SynInfo;
|
||||||
import org.eclipse.jetty.spdy.client.SPDYClient;
|
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.spdy.server.http.SPDYTestUtils;
|
||||||
|
import org.eclipse.jetty.toolchain.test.TestTracker;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
import org.eclipse.jetty.util.IO;
|
import org.eclipse.jetty.util.IO;
|
||||||
|
@ -71,33 +68,19 @@ import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestWatcher;
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
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
|
@Ignore
|
||||||
@RunWith(value = Parameterized.class)
|
@RunWith(value = Parameterized.class)
|
||||||
public class ProxySPDYToHTTPLoadTest
|
public abstract class ProxySPDYToHTTPLoadTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(ProxySPDYToHTTPLoadTest.class);
|
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
|
@Parameterized.Parameters
|
||||||
public static Collection<Short[]> parameters()
|
public static Collection<Short[]> parameters()
|
||||||
|
@ -105,6 +88,12 @@ public class ProxySPDYToHTTPLoadTest
|
||||||
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
|
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 SPDYClient.Factory factory;
|
||||||
private Server server1;
|
private Server server1;
|
||||||
private Server server2;
|
private Server server2;
|
||||||
|
@ -112,9 +101,10 @@ public class ProxySPDYToHTTPLoadTest
|
||||||
private ServerConnector proxyConnector;
|
private ServerConnector proxyConnector;
|
||||||
private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
|
private SslContextFactory sslContextFactory = SPDYTestUtils.newSslContextFactory();
|
||||||
|
|
||||||
public ProxySPDYToHTTPLoadTest(short version)
|
public ProxySPDYToHTTPLoadTest(short version, NegotiatingServerConnectionFactory negotiator)
|
||||||
{
|
{
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
this.negotiator = negotiator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -188,7 +178,7 @@ public class ProxySPDYToHTTPLoadTest
|
||||||
proxyEngineSelector.putProxyServerInfo("127.0.0.2", new ProxyEngineSelector.ProxyServerInfo("http/1.1",
|
proxyEngineSelector.putProxyServerInfo("127.0.0.2", new ProxyEngineSelector.ProxyServerInfo("http/1.1",
|
||||||
server2.getHostName(), server2.getPort()));
|
server2.getHostName(), server2.getPort()));
|
||||||
|
|
||||||
proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, proxyEngineSelector);
|
proxyConnector = new HTTPSPDYProxyServerConnector(proxy, sslContextFactory, new HttpConfiguration(), proxyEngineSelector, negotiator);
|
||||||
proxyConnector.setPort(0);
|
proxyConnector.setPort(0);
|
||||||
proxyConnector.setIdleTimeout(proxyConnectorTimeout);
|
proxyConnector.setIdleTimeout(proxyConnectorTimeout);
|
||||||
proxy.addConnector(proxyConnector);
|
proxy.addConnector(proxyConnector);
|
||||||
|
|
|
@ -18,11 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server.proxy;
|
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.BufferedReader;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -32,7 +27,6 @@ import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
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.client.SPDYClient;
|
||||||
import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
|
import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
|
||||||
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
|
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.Callback;
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -71,36 +66,26 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestWatcher;
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
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)
|
@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
|
@Parameterized.Parameters
|
||||||
public static Collection<Short[]> parameters()
|
public static Collection<Short[]> parameters()
|
||||||
{
|
{
|
||||||
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
|
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 SPDYClient.Factory factory;
|
||||||
private Server server;
|
private Server server;
|
||||||
private Server proxy;
|
private Server proxy;
|
||||||
|
|
|
@ -18,10 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server.proxy;
|
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.io.ByteArrayOutputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
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.SPDYServerConnectionFactory;
|
||||||
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
|
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
|
||||||
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
|
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.Callback;
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
|
@ -60,36 +57,25 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestWatcher;
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
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)
|
@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
|
@Parameterized.Parameters
|
||||||
public static Collection<Short[]> parameters()
|
public static Collection<Short[]> parameters()
|
||||||
{
|
{
|
||||||
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
|
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 UUID_HEADER_NAME = "uuidHeader";
|
||||||
private static final String SERVER_ID_HEADER = "serverId";
|
private static final String SERVER_ID_HEADER = "serverId";
|
||||||
private SPDYClient.Factory factory;
|
private SPDYClient.Factory factory;
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server.proxy;
|
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.io.ByteArrayOutputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.charset.StandardCharsets;
|
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.SPDYServerConnectionFactory;
|
||||||
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
|
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
|
||||||
import org.eclipse.jetty.spdy.server.http.SPDYTestUtils;
|
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.Callback;
|
||||||
import org.eclipse.jetty.util.Fields;
|
import org.eclipse.jetty.util.Fields;
|
||||||
import org.eclipse.jetty.util.Promise;
|
import org.eclipse.jetty.util.Promise;
|
||||||
|
@ -61,35 +59,24 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestWatcher;
|
|
||||||
import org.junit.runner.Description;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
@RunWith(value = Parameterized.class)
|
@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
|
@Parameterized.Parameters
|
||||||
public static Collection<Short[]> parameters()
|
public static Collection<Short[]> parameters()
|
||||||
{
|
{
|
||||||
return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
|
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 SPDYClient.Factory factory;
|
||||||
private Server server;
|
private Server server;
|
||||||
private Server proxy;
|
private Server proxy;
|
||||||
|
|
|
@ -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>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server;
|
package org.eclipse.jetty.spdy.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -45,8 +42,14 @@ import org.junit.runners.Parameterized;
|
||||||
import org.junit.runners.Parameterized.Parameter;
|
import org.junit.runners.Parameterized.Parameter;
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
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)
|
@RunWith(Parameterized.class)
|
||||||
public class NpnModuleTest
|
public class NPNModuleTest
|
||||||
{
|
{
|
||||||
/** This is here to prevent pointless download attempts */
|
/** This is here to prevent pointless download attempts */
|
||||||
private static final List<String> KNOWN_GOOD_NPN_URLS = new ArrayList<>();
|
private static final List<String> KNOWN_GOOD_NPN_URLS = new ArrayList<>();
|
||||||
|
@ -66,7 +69,7 @@ public class NpnModuleTest
|
||||||
@Parameters(name = "{index}: mod:{0}")
|
@Parameters(name = "{index}: mod:{0}")
|
||||||
public static List<Object[]> data()
|
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<>();
|
List<Object[]> data = new ArrayList<>();
|
||||||
for (File file : npnBootModDir.listFiles())
|
for (File file : npnBootModDir.listFiles())
|
||||||
{
|
{
|
||||||
|
@ -86,8 +89,8 @@ public class NpnModuleTest
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void initBaseHome()
|
public static void initBaseHome()
|
||||||
{
|
{
|
||||||
File homeDir = MavenTestingUtils.getProjectDir("src/main/config");
|
File homeDir = MavenTestingUtils.getProjectDir("../spdy-http-server/src/main/config");
|
||||||
File baseDir = MavenTestingUtils.getTargetTestingDir(NpnModuleTest.class.getName());
|
File baseDir = MavenTestingUtils.getTargetTestingDir(NPNModuleTest.class.getName());
|
||||||
FS.ensureEmpty(baseDir);
|
FS.ensureEmpty(baseDir);
|
||||||
basehome = new BaseHome(homeDir,baseDir);
|
basehome = new BaseHome(homeDir,baseDir);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +142,7 @@ public class NpnModuleTest
|
||||||
|
|
||||||
public static void main(String[] args)
|
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);
|
FS.ensureEmpty(outputDir);
|
||||||
for (String ref : KNOWN_GOOD_NPN_URLS)
|
for (String ref : KNOWN_GOOD_NPN_URLS)
|
||||||
{
|
{
|
|
@ -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 "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,39 +19,20 @@
|
||||||
package org.eclipse.jetty.spdy.server;
|
package org.eclipse.jetty.spdy.server;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
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.GoAwayInfo;
|
||||||
|
import org.eclipse.jetty.spdy.api.SPDY;
|
||||||
import org.eclipse.jetty.spdy.api.Session;
|
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.Assert;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
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
|
@Test
|
||||||
@Ignore
|
|
||||||
public void testSSLEngineLeak() throws Exception
|
public void testSSLEngineLeak() throws Exception
|
||||||
{
|
{
|
||||||
System.gc();
|
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
|
// Allow the close to arrive to the server and the selector to process it
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
|
|
||||||
// Perform GC to be sure that the WeakHashMap is cleared
|
// Perform GC to be sure that the map is cleared
|
||||||
Thread.sleep(1000);
|
|
||||||
System.gc();
|
System.gc();
|
||||||
|
Thread.sleep(1000);
|
||||||
|
|
||||||
// Check that the WeakHashMap is empty
|
// Check that the map is empty
|
||||||
if (objects.size()!=initialSize)
|
if (objects.size() != initialSize)
|
||||||
{
|
{
|
||||||
System.err.println(objects);
|
System.err.println(objects);
|
||||||
server.dumpStdErr();
|
server.dumpStdErr();
|
||||||
|
@ -83,7 +64,8 @@ public class SSLEngineLeakTest extends AbstractTest
|
||||||
|
|
||||||
private void avoidStackLocalVariables() throws Exception
|
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));
|
session.goAway(new GoAwayInfo(5, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,48 +23,20 @@ import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
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.BufferUtil;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
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
|
@Test
|
||||||
public void testGentleCloseDuringHandshake() throws Exception
|
public void testGentleCloseDuringHandshake() throws Exception
|
||||||
{
|
{
|
||||||
InetSocketAddress address = startServer(version, null);
|
InetSocketAddress address = prepare();
|
||||||
SslContextFactory sslContextFactory = newSslContextFactory();
|
SslContextFactory sslContextFactory = newSslContextFactory();
|
||||||
sslContextFactory.start();
|
sslContextFactory.start();
|
||||||
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
|
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
|
||||||
|
@ -124,7 +96,7 @@ public class SSLSynReplyTest extends SynReplyTest
|
||||||
@Test
|
@Test
|
||||||
public void testAbruptCloseDuringHandshake() throws Exception
|
public void testAbruptCloseDuringHandshake() throws Exception
|
||||||
{
|
{
|
||||||
InetSocketAddress address = startServer(version, null);
|
InetSocketAddress address = prepare();
|
||||||
SslContextFactory sslContextFactory = newSslContextFactory();
|
SslContextFactory sslContextFactory = newSslContextFactory();
|
||||||
sslContextFactory.start();
|
sslContextFactory.start();
|
||||||
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
|
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
|
#org.eclipse.jetty.spdy.LEVEL=DEBUG
|
|
@ -17,36 +17,6 @@
|
||||||
<url>http://www.eclipse.org/jetty</url>
|
<url>http://www.eclipse.org/jetty</url>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<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>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -18,146 +18,49 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server;
|
package org.eclipse.jetty.spdy.server;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
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.io.EndPoint;
|
||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
import org.eclipse.jetty.npn.NextProtoNego;
|
||||||
import org.eclipse.jetty.server.ConnectionFactory;
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
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.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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 static final Logger LOG = Log.getLogger(NPNServerConnection.class);
|
||||||
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
|
|
||||||
|
|
||||||
public NPNServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, List<String> protocols, String defaultProtocol)
|
public NPNServerConnection(EndPoint endPoint, SSLEngine engine, Connector connector, List<String> protocols, String defaultProtocol)
|
||||||
{
|
{
|
||||||
super(endPoint, connector.getExecutor());
|
super(connector, endPoint, engine, protocols, defaultProtocol);
|
||||||
this.connector = connector;
|
|
||||||
this.protocols = protocols;
|
|
||||||
this.defaultProtocol = defaultProtocol;
|
|
||||||
this.engine = engine;
|
|
||||||
NextProtoNego.put(engine, this);
|
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
|
@Override
|
||||||
public void unsupported()
|
public void unsupported()
|
||||||
{
|
{
|
||||||
protocolSelected(defaultProtocol);
|
protocolSelected(getDefaultProtocol());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> protocols()
|
public List<String> protocols()
|
||||||
{
|
{
|
||||||
return protocols;
|
return getProtocols();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void protocolSelected(String protocol)
|
public void protocolSelected(String protocol)
|
||||||
{
|
{
|
||||||
LOG.debug("{} protocol selected {}", this, protocol);
|
LOG.debug("{} protocol selected {}", this, protocol);
|
||||||
nextProtocol = protocol != null ? protocol : defaultProtocol;
|
setProtocol(protocol != null ? protocol : getDefaultProtocol());
|
||||||
NextProtoNego.remove(engine);
|
NextProtoNego.remove(getSSLEngine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
NextProtoNego.remove(engine);
|
NextProtoNego.remove(getSSLEngine());
|
||||||
EndPoint endPoint = getEndPoint();
|
super.close();
|
||||||
endPoint.shutdownOutput();
|
|
||||||
endPoint.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,106 +16,45 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server;
|
package org.eclipse.jetty.spdy.server;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.net.ssl.SSLEngine;
|
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.EndPoint;
|
||||||
import org.eclipse.jetty.io.ssl.SslConnection;
|
|
||||||
import org.eclipse.jetty.npn.NextProtoNego;
|
import org.eclipse.jetty.npn.NextProtoNego;
|
||||||
import org.eclipse.jetty.server.AbstractConnectionFactory;
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.Connector;
|
||||||
import org.eclipse.jetty.util.annotation.Name;
|
import org.eclipse.jetty.util.annotation.Name;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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 static final Logger LOG = Log.getLogger(NPNServerConnectionFactory.class);
|
||||||
private final List<String> _protocols;
|
|
||||||
private String _defaultProtocol;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
public NPNServerConnectionFactory(@Name("protocols") String... protocols)
|
||||||
/**
|
|
||||||
* @param protocols List of supported protocols in priority order
|
|
||||||
*/
|
|
||||||
public NPNServerConnectionFactory(@Name("protocols")String... protocols)
|
|
||||||
{
|
{
|
||||||
super("npn");
|
super("npn", protocols);
|
||||||
_protocols=Arrays.asList(protocols);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (NextProtoNego.class.getClassLoader()!=null)
|
ClassLoader npnClassLoader = NextProtoNego.class.getClassLoader();
|
||||||
|
if (npnClassLoader != null)
|
||||||
{
|
{
|
||||||
LOG.warn("NextProtoNego not from bootloader classloader: "+NextProtoNego.class.getClassLoader());
|
LOG.warn("NPN must be in the boot classloader, not in: " + npnClassLoader);
|
||||||
throw new IllegalStateException("NextProtoNego not on bootloader");
|
throw new IllegalStateException("NPN must be in the boot classloader");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Throwable th)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.warn("NextProtoNego not available: "+th);
|
LOG.warn("NPN not available: " + x);
|
||||||
throw new IllegalStateException("NextProtoNego not available",th);
|
throw new IllegalStateException("NPN not available", x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDefaultProtocol()
|
|
||||||
{
|
|
||||||
return _defaultProtocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultProtocol(String defaultProtocol)
|
|
||||||
{
|
|
||||||
_defaultProtocol = defaultProtocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getProtocols()
|
|
||||||
{
|
|
||||||
return _protocols;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection newConnection(Connector connector, EndPoint endPoint)
|
protected AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
|
||||||
{
|
{
|
||||||
List<String> protocols=_protocols;
|
return new NPNServerConnection(endPoint, engine, connector, protocols, defaultProtocol);
|
||||||
if (protocols==null || protocols.size()==0)
|
|
||||||
{
|
|
||||||
protocols=connector.getProtocols();
|
|
||||||
for (Iterator<String> i=protocols.iterator();i.hasNext();)
|
|
||||||
{
|
|
||||||
String protocol=i.next();
|
|
||||||
if (protocol.startsWith("SSL-")||protocol.equals("NPN"))
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String dft=_defaultProtocol;
|
|
||||||
if (dft==null)
|
|
||||||
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(new NPNServerConnection(endPoint, engine, connector,protocols,_defaultProtocol),connector,endPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return String.format("%s@%x{%s,%s,%s}",this.getClass().getSimpleName(),hashCode(),getProtocol(),getDefaultProtocol(),getProtocols());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,19 +47,34 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
@ManagedObject("SPDY Server Connection Factory")
|
@ManagedObject("SPDY Server Connection Factory")
|
||||||
public class SPDYServerConnectionFactory extends AbstractConnectionFactory
|
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()
|
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
|
try
|
||||||
{
|
{
|
||||||
Class<?> npn = ClassLoader.getSystemClassLoader().loadClass("org.eclipse.jetty.npn.NextProtoNego");
|
Class<?> klass = ClassLoader.getSystemClassLoader().loadClass(className);
|
||||||
if (npn.getClassLoader() != null)
|
if (klass.getClassLoader() != null)
|
||||||
throw new IllegalStateException("NextProtoNego must be on JVM boot path");
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.spdy.server;
|
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.HttpConnectionFactory;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
@ -30,23 +31,21 @@ public class SPDYServerConnector extends ServerConnector
|
||||||
{
|
{
|
||||||
public SPDYServerConnector(Server server, ServerSessionFrameListener listener)
|
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)
|
public SPDYServerConnector(Server server, SslContextFactory sslContextFactory, ServerSessionFrameListener listener)
|
||||||
{
|
{
|
||||||
super(server,
|
this(server, sslContextFactory, listener, new NPNServerConnectionFactory("spdy/3", "spdy/2", "http/1.1"));
|
||||||
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");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
262
pom.xml
262
pom.xml
|
@ -814,137 +814,137 @@
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u9</id>
|
<id>7u9</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_9</value>
|
<value>1.7.0_9</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.3.v20130313</npn.version>
|
<npn.version>1.1.3.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u10</id>
|
<id>7u10</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_10</value>
|
<value>1.7.0_10</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.3.v20130313</npn.version>
|
<npn.version>1.1.3.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u11</id>
|
<id>7u11</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_11</value>
|
<value>1.7.0_11</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.3.v20130313</npn.version>
|
<npn.version>1.1.3.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u13</id>
|
<id>7u13</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_13</value>
|
<value>1.7.0_13</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.4.v20130313</npn.version>
|
<npn.version>1.1.4.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u15</id>
|
<id>7u15</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_15</value>
|
<value>1.7.0_15</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.5.v20130313</npn.version>
|
<npn.version>1.1.5.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u17</id>
|
<id>7u17</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_17</value>
|
<value>1.7.0_17</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.5.v20130313</npn.version>
|
<npn.version>1.1.5.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u21</id>
|
<id>7u21</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_21</value>
|
<value>1.7.0_21</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.5.v20130313</npn.version>
|
<npn.version>1.1.5.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u25</id>
|
<id>7u25</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_25</value>
|
<value>1.7.0_25</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.5.v20130313</npn.version>
|
<npn.version>1.1.5.v20130313</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u40</id>
|
<id>7u40</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_40</value>
|
<value>1.7.0_40</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.6.v20130911</npn.version>
|
<npn.version>1.1.6.v20130911</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u45</id>
|
<id>7u45</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_45</value>
|
<value>1.7.0_45</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.6.v20130911</npn.version>
|
<npn.version>1.1.6.v20130911</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>7u51</id>
|
<id>7u51</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>java.version</name>
|
<name>java.version</name>
|
||||||
<value>1.7.0_51</value>
|
<value>1.7.0_51</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<npn.version>1.1.6.v20130911</npn.version>
|
<npn.version>1.1.6.v20130911</npn.version>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class TestTransparentProxyServer
|
||||||
|
|
||||||
|
|
||||||
// Spdy Connector
|
// Spdy Connector
|
||||||
SPDYServerConnectionFactory.checkNPNAvailable();
|
SPDYServerConnectionFactory.checkProtocolNegotiationAvailable();
|
||||||
PushStrategy push = new ReferrerPushStrategy();
|
PushStrategy push = new ReferrerPushStrategy();
|
||||||
HTTPSPDYServerConnectionFactory spdy2 = new HTTPSPDYServerConnectionFactory(2,config,push);
|
HTTPSPDYServerConnectionFactory spdy2 = new HTTPSPDYServerConnectionFactory(2,config,push);
|
||||||
spdy2.setInputBufferSize(8192);
|
spdy2.setInputBufferSize(8192);
|
||||||
|
|
Loading…
Reference in New Issue