Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimone Bordet2015-03-02 12:06:16 +0000
committerSimone Bordet2015-03-02 12:17:26 +0000
commit9f769950869ab639fdb084a66da5369ba42a613a (patch)
treec7ceb194673d89a60be0033c250e4e994c53fc3d
parent46bcc31f3b55270dfa8570cd72a0c93bdadbce05 (diff)
downloadorg.eclipse.jetty.project-9f769950869ab639fdb084a66da5369ba42a613a.tar.gz
org.eclipse.jetty.project-9f769950869ab639fdb084a66da5369ba42a613a.tar.xz
org.eclipse.jetty.project-9f769950869ab639fdb084a66da5369ba42a613a.zip
Restored ALPN tests.
-rw-r--r--jetty-http2/http2-alpn-tests/pom.xml89
-rw-r--r--jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java311
-rw-r--r--jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java78
-rw-r--r--jetty-http2/http2-alpn-tests/src/test/resources/jetty-logging.properties3
-rw-r--r--jetty-http2/http2-alpn-tests/src/test/resources/keystore.jksbin0 -> 2206 bytes
-rw-r--r--jetty-http2/http2-alpn-tests/src/test/resources/truststore.jksbin0 -> 916 bytes
-rw-r--r--jetty-http2/pom.xml8
7 files changed, 485 insertions, 4 deletions
diff --git a/jetty-http2/http2-alpn-tests/pom.xml b/jetty-http2/http2-alpn-tests/pom.xml
new file mode 100644
index 0000000000..e4a343409a
--- /dev/null
+++ b/jetty-http2/http2-alpn-tests/pom.xml
@@ -0,0 +1,89 @@
+<?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.http2</groupId>
+ <artifactId>http2-parent</artifactId>
+ <version>9.3.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>http2-alpn-tests</artifactId>
+ <name>Jetty :: HTTP2 :: ALPN Tests</name>
+
+ <properties>
+ <bundle-symbolic-name>${project.groupId}.alpn.tests</bundle-symbolic-name>
+ </properties>
+
+ <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.alpn</groupId>
+ <artifactId>alpn-boot</artifactId>
+ <version>${alpn.version}</version>
+ <type>jar</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}/alpn</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty.alpn</groupId>
+ <artifactId>alpn-api</artifactId>
+ <version>${alpn.api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-alpn-server</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</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.http2</groupId>
+ <artifactId>http2-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <artifactId>jetty-test-helper</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java
new file mode 100644
index 0000000000..7432381ef1
--- /dev/null
+++ b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/ALPNNegotiationTest.java
@@ -0,0 +1,311 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.http2.alpn.tests;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.alpn.ALPN;
+import org.eclipse.jetty.util.BufferUtil;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ALPNNegotiationTest extends AbstractALPNTest
+{
+ @Test
+ public void testGentleCloseDuringHandshake() throws Exception
+ {
+ InetSocketAddress address = prepare();
+ SslContextFactory sslContextFactory = newSslContextFactory();
+ sslContextFactory.start();
+ SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
+ sslEngine.setUseClientMode(true);
+ ALPN.put(sslEngine, new ALPN.ClientProvider()
+ {
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public List<String> protocols()
+ {
+ return Arrays.asList("h2");
+ }
+
+ @Override
+ public void selected(String protocol)
+ {
+ }
+ });
+ sslEngine.beginHandshake();
+
+ ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
+ sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
+ encrypted.flip();
+
+ try (SocketChannel channel = SocketChannel.open(address))
+ {
+ // Send ClientHello, immediately followed by TLS Close Alert and then by FIN
+ channel.write(encrypted);
+ sslEngine.closeOutbound();
+ encrypted.clear();
+ sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
+ encrypted.flip();
+ channel.write(encrypted);
+ channel.shutdownOutput();
+
+ // Read ServerHello from server
+ encrypted.clear();
+ int read = channel.read(encrypted);
+ encrypted.flip();
+ Assert.assertTrue(read > 0);
+ // Cannot decrypt, as the SSLEngine has been already closed
+
+ // Now if we read more, we should either read the TLS Close Alert, or directly -1
+ encrypted.clear();
+ read = channel.read(encrypted);
+ // Sending a TLS Close Alert during handshake results in an exception when
+ // unwrapping that the server react to by closing the connection abruptly.
+ Assert.assertTrue(read < 0);
+ }
+ }
+
+ @Test
+ public void testAbruptCloseDuringHandshake() throws Exception
+ {
+ InetSocketAddress address = prepare();
+ SslContextFactory sslContextFactory = newSslContextFactory();
+ sslContextFactory.start();
+ SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
+ sslEngine.setUseClientMode(true);
+ ALPN.put(sslEngine, new ALPN.ClientProvider()
+ {
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public List<String> protocols()
+ {
+ return Arrays.asList("h2");
+ }
+
+ @Override
+ public void selected(String s)
+ {
+ }
+ });
+ sslEngine.beginHandshake();
+
+ ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
+ sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
+ encrypted.flip();
+
+ try (SocketChannel channel = SocketChannel.open(address))
+ {
+ // Send ClientHello, immediately followed by FIN (no TLS Close Alert)
+ channel.write(encrypted);
+ channel.shutdownOutput();
+
+ // Read ServerHello from server
+ encrypted.clear();
+ int read = channel.read(encrypted);
+ encrypted.flip();
+ Assert.assertTrue(read > 0);
+ ByteBuffer decrypted = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
+ sslEngine.unwrap(encrypted, decrypted);
+
+ // Now if we read more, we should either read the TLS Close Alert, or directly -1
+ encrypted.clear();
+ read = channel.read(encrypted);
+ // Since we have close the connection abruptly, the server also does so
+ Assert.assertTrue(read < 0);
+ }
+ }
+
+ @Test
+ public void testClientAdvertisingHTTPServerSpeaksHTTP() throws Exception
+ {
+ InetSocketAddress address = prepare();
+
+ 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);
+
+ ALPN.put(client, new ALPN.ClientProvider()
+ {
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public List<String> protocols()
+ {
+ return Arrays.asList("http/1.1");
+ }
+
+ @Override
+ public void selected(String protocol)
+ {
+ Assert.assertEquals("http/1.1", 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 testClientAdvertisingMultipleProtocolsServerSpeaksHTTPWhenNegotiated() throws Exception
+ {
+ InetSocketAddress address = prepare();
+
+ 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);
+
+ ALPN.put(client, new ALPN.ClientProvider()
+ {
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public List<String> protocols()
+ {
+ return Arrays.asList("unknown/1.0", "http/1.1");
+ }
+
+ @Override
+ public void selected(String protocol)
+ {
+ Assert.assertEquals("http/1.1", 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 testClientNotSupportingALPNServerSpeaksDefaultProtocol() throws Exception
+ {
+ InetSocketAddress address = prepare();
+
+ 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);
+
+ ALPN.put(client, new ALPN.ClientProvider()
+ {
+ @Override
+ public void unsupported()
+ {
+ }
+
+ @Override
+ public List<String> protocols()
+ {
+ return null;
+ }
+
+ @Override
+ public void selected(String s)
+ {
+ }
+ });
+
+ client.startHandshake();
+
+ // Verify that the server really speaks http/1.1
+
+ OutputStream output = client.getOutputStream();
+ output.write(("" +
+ "GET / HTTP/1.1\r\n" +
+ "Host: localhost:" + address.getPort() + "\r\n" +
+ "\r\n" +
+ "").getBytes(StandardCharsets.UTF_8));
+ output.flush();
+
+ InputStream input = client.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
+ String line = reader.readLine();
+ Assert.assertTrue(line.contains(" 404 "));
+ }
+ }
+}
diff --git a/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java
new file mode 100644
index 0000000000..2a4b660510
--- /dev/null
+++ b/jetty-http2/http2-alpn-tests/src/test/java/org/eclipse/jetty/http2/alpn/tests/AbstractALPNTest.java
@@ -0,0 +1,78 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2015 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.http2.alpn.tests;
+
+import java.net.InetSocketAddress;
+
+import org.eclipse.jetty.alpn.ALPN;
+import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
+import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.toolchain.test.TestTracker;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.junit.After;
+import org.junit.Rule;
+
+public class AbstractALPNTest
+{
+ @Rule
+ public final TestTracker tracker = new TestTracker();
+ protected Server server;
+ protected ServerConnector connector;
+
+ protected InetSocketAddress prepare() throws Exception
+ {
+ server = new Server();
+ HttpConfiguration httpConfiguration = new HttpConfiguration();
+ HttpConnectionFactory h1 = new HttpConnectionFactory(httpConfiguration);
+ HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(httpConfiguration);
+ ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
+ alpn.setDefaultProtocol(h1.getProtocol());
+ connector = new ServerConnector(server, newSslContextFactory(), alpn, h1, h2);
+ connector.setPort(0);
+ connector.setIdleTimeout(30000);
+ server.addConnector(connector);
+ server.start();
+
+ ALPN.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.setIncludeProtocols("TLSv1.2");
+ sslContextFactory.setIncludeCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+ return sslContextFactory;
+ }
+
+ @After
+ public void dispose() throws Exception
+ {
+ server.stop();
+ }
+}
diff --git a/jetty-http2/http2-alpn-tests/src/test/resources/jetty-logging.properties b/jetty-http2/http2-alpn-tests/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..29a0dfa448
--- /dev/null
+++ b/jetty-http2/http2-alpn-tests/src/test/resources/jetty-logging.properties
@@ -0,0 +1,3 @@
+org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
+org.eclipse.jetty.alpn.LEVEL=DEBUG
+org.eclipse.jetty.http2.LEVEL=DEBUG
diff --git a/jetty-http2/http2-alpn-tests/src/test/resources/keystore.jks b/jetty-http2/http2-alpn-tests/src/test/resources/keystore.jks
new file mode 100644
index 0000000000..428ba54776
--- /dev/null
+++ b/jetty-http2/http2-alpn-tests/src/test/resources/keystore.jks
Binary files differ
diff --git a/jetty-http2/http2-alpn-tests/src/test/resources/truststore.jks b/jetty-http2/http2-alpn-tests/src/test/resources/truststore.jks
new file mode 100644
index 0000000000..839cb8c351
--- /dev/null
+++ b/jetty-http2/http2-alpn-tests/src/test/resources/truststore.jks
Binary files differ
diff --git a/jetty-http2/pom.xml b/jetty-http2/pom.xml
index 82bdb9ebd2..f4e96f7075 100644
--- a/jetty-http2/pom.xml
+++ b/jetty-http2/pom.xml
@@ -13,12 +13,12 @@
<name>Jetty :: HTTP2</name>
<modules>
- <module>http2-hpack</module>
- <module>http2-common</module>
+ <module>http2-alpn-tests</module>
<module>http2-client</module>
- <module>http2-server</module>
+ <module>http2-common</module>
+ <module>http2-hpack</module>
<module>http2-http-client-transport</module>
+ <module>http2-server</module>
</modules>
-
</project>

Back to the top