Author: markt Date: Mon Jun 1 09:26:13 2015 New Revision: 1682848 URL: http://svn.apache.org/r1682848 Log: Start to provide unit tests for the HTTP/2 implementation.
Added: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Base.java (with props) tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2.java (with props) tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2_1.java (with props) Added: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Base.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Base.java?rev=1682848&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Base.java (added) +++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Base.java Mon Jun 1 09:26:13 2015 @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.coyote.http2; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.charset.StandardCharsets; + +import javax.net.SocketFactory; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.junit.Assert; +import org.junit.Before; + +import org.apache.catalina.Context; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.codec.binary.Base64; + + +/** + * Tests for compliance with the <a href="https://tools.ietf.org/html/rfc7540"> + * HTTP/2 specification</a>. + */ +public abstract class TestHttp2Base extends TomcatBaseTest { + + private static final String HTTP2_SETTINGS; + + static { + byte[] empty = new byte[0]; + HTTP2_SETTINGS = Base64.encodeBase64String(empty); + } + + private Socket s; + protected Http2Parser parser; + protected OutputStream os; + + + @Before + public void setup() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + // Enable HTTP/2 + Connector connector = tomcat.getConnector(); + Http2Protocol http2Protocol = new Http2Protocol(); + // Short timeouts for now. May need to increase these for CI systems. + http2Protocol.setReadTimeout(2000); + http2Protocol.setKeepAliveTimeout(5000); + http2Protocol.setWriteTimeout(2000); + connector.addUpgradeProtocol(http2Protocol); + + // Add a web application + Context ctxt = tomcat.addContext("", null); + Tomcat.addServlet(ctxt, "simple", new SimpleServlet()); + ctxt.addServletMapping("/*", "simple"); + + // Start the Tomcat instance + tomcat.start(); + + // Open a connection + s = SocketFactory.getDefault().createSocket("localhost", getPort()); + s.setSoTimeout(30000); + + os = s.getOutputStream(); + InputStream is = s.getInputStream(); + + TestInput testInput = new TestInput(is); + parser = new Http2Parser(testInput); + } + + + protected void doHttpUpgrade() throws IOException { + byte[] upgradeRequest = ("GET / HTTP/1.1\r\n" + + "Host: localhost:" + getPort() + "\r\n" + + "Connection: Upgrade, HTTP2-Settings\r\n" + + "Upgrade: h2c\r\n" + + "HTTP2-Settings: "+ HTTP2_SETTINGS + "\r\n" + + "\r\n").getBytes(StandardCharsets.ISO_8859_1); + os.write(upgradeRequest); + os.flush(); + + Assert.assertTrue("Failed to read HTTP Upgrade response", parser.readHttpUpgradeResponse()); + + } + + + private static class TestInput implements Http2Parser.Input { + + private final InputStream is; + + + public TestInput(InputStream is) { + this.is = is; + } + + + @Override + public boolean fill(byte[] data, boolean block) throws IOException { + // Note: Block is ignored for this test class. Reads always block. + int off = 0; + int len = data.length; + while (len > 0) { + int read = is.read(data, off, len); + if (read == -1) { + throw new IOException("End of input stream"); + } + off += read; + len -= read; + } + return true; + } + } + + + private static class SimpleServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + // Generate content with a simple known format. + resp.setContentType("application/octet-stream"); + OutputStream os = resp.getOutputStream(); + byte[] data = new byte[2]; + // 1024 * 16 * 2 bytes = 32k of content. + for (int i = 0; i < 1024 * 16; i++) { + data[0] = (byte) (i & 0xFF); + data[1] = (byte) ((i >> 8) & 0xFF); + os.write(data); + } + } + } +} Propchange: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Base.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2.java?rev=1682848&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2.java (added) +++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2.java Mon Jun 1 09:26:13 2015 @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.coyote.http2; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +/** + * Unit tests for Section 3.2 of + * <a href="https://tools.ietf.org/html/rfc7540">RFC 7540</a>. + * <br> + * The order of tests in this class is aligned with the order of the + * requirements in the RFC. + */ +public class TestHttp2Section_3_2 extends TestHttp2Base { + + // TODO: Test initial requests with bodies of various sizes + + // TODO: Test response with HTTP/2 is not enabled + + // TODO: Test HTTP upgrade with h2 rather tan h2c + + @Test(timeout=10000) + public void testConnectionNoPreface() throws IOException { + doHttpUpgrade(); + + // If we don't send the preface the server should kill the connection. + try { + // Make the parser read something. + parser.readFrame(true); + } catch (IOException ioe) { + // Expected because the server is going to drop the connection. + } + } + + + @Test(timeout=10000) + public void testConnectionIncompletePrefaceStart() throws IOException { + doHttpUpgrade(); + + // If we send an incomplete preface the server should kill the + // connection. + os.write("PRI * HTTP/2.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + try { + // Make the parser read something. + parser.readFrame(true); + } catch (IOException ioe) { + // Expected because the server is going to drop the connection. + } + } + + + @Test(timeout=10000) + public void testConnectionInvalidPrefaceStart() throws IOException { + doHttpUpgrade(); + + // If we send an incomplete preface the server should kill the + // connection. + os.write("xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxxxxxxxxx".getBytes( + StandardCharsets.ISO_8859_1)); + os.flush(); + try { + // Make the parser read something. + parser.readFrame(true); + } catch (IOException ioe) { + // Expected because the server is going to drop the connection. + } + } + + + // TODO: Test if server sends settings frame + + // TODO: Test if client doesn't send SETTINGS as part of the preface + + // TODO: Test response is received on stream 1 +} Propchange: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2_1.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2_1.java?rev=1682848&view=auto ============================================================================== --- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2_1.java (added) +++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2_1.java Mon Jun 1 09:26:13 2015 @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.coyote.http2; + +public class TestHttp2Section_3_2_1 extends TestHttp2Base { + + // TODO: Test zero Http2-Settings headers + + // TODO: Test multiple Http2-Settings headers + + // TODO: Test trailing '=' are omitted + + // TODO: Test invalid Http2-Settings header (wrong length, invalid encoding) +} Propchange: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_3_2_1.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org