This is an automated email from the ASF dual-hosted git repository. remm pushed a commit to branch 8.5.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 932685c1fca196d9a6a6b41c0fda76b44d463ad4 Author: remm <r...@apache.org> AuthorDate: Wed Mar 4 12:02:27 2020 +0100 Hack in TLS support for HTTP/2 tests Try to reproduce BZ64192 but it's not misbehaving as expected. Finding flow control problems with non async. --- test/org/apache/coyote/http2/Http2TestBase.java | 42 +++++++- test/org/apache/coyote/http2/TestLargeUpload.java | 112 +++++++++++++++++++++ test/org/apache/tomcat/util/net/TesterSupport.java | 2 +- 3 files changed, 150 insertions(+), 6 deletions(-) diff --git a/test/org/apache/coyote/http2/Http2TestBase.java b/test/org/apache/coyote/http2/Http2TestBase.java index 3e611c5..b3e10b1 100644 --- a/test/org/apache/coyote/http2/Http2TestBase.java +++ b/test/org/apache/coyote/http2/Http2TestBase.java @@ -52,6 +52,7 @@ import org.apache.coyote.http2.Http2Parser.Output; import org.apache.tomcat.util.codec.binary.Base64; import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.http.MimeHeaders; +import org.apache.tomcat.util.net.TesterSupport; /** * Tests for compliance with the <a href="https://tools.ietf.org/html/rfc7540"> @@ -103,9 +104,13 @@ public abstract class Http2TestBase extends TomcatBaseTest { * that the first response is correctly received. */ protected void http2Connect() throws Exception { - enableHttp2(); + http2Connect(false); + } + + protected void http2Connect(boolean tls) throws Exception { + enableHttp2(tls); configureAndStartWebApplication(); - openClientConnection(); + openClientConnection(tls); doHttpUpgrade(); sendClientPreface(); validateHttp2InitialResponse(); @@ -538,8 +543,17 @@ public abstract class Http2TestBase extends TomcatBaseTest { } protected void enableHttp2(long maxConcurrentStreams) { - Connector connector = getTomcatInstance().getConnector(); - http2Protocol = new Http2Protocol(); + enableHttp2(maxConcurrentStreams, false); + } + + protected void enableHttp2(boolean tls) { + enableHttp2(200, tls); + } + + protected void enableHttp2(long maxConcurrentStreams, boolean tls) { + Tomcat tomcat = getTomcatInstance(); + Connector connector = tomcat.getConnector(); + http2Protocol = new UpgradableHttp2Protocol(); // Short timeouts for now. May need to increase these for CI systems. http2Protocol.setReadTimeout(6000); http2Protocol.setWriteTimeout(6000); @@ -548,8 +562,18 @@ public abstract class Http2TestBase extends TomcatBaseTest { http2Protocol.setStreamWriteTimeout(3000); http2Protocol.setMaxConcurrentStreams(maxConcurrentStreams); connector.addUpgradeProtocol(http2Protocol); + if (tls) { + // Enable TLS + TesterSupport.initSsl(tomcat); + } } + private class UpgradableHttp2Protocol extends Http2Protocol { + @Override + public String getHttpUpgradeName(boolean isSSLEnabled) { + return "h2c"; + } + } protected void configureAndStartWebApplication() throws LifecycleException { Tomcat tomcat = getTomcatInstance(); @@ -571,8 +595,13 @@ public abstract class Http2TestBase extends TomcatBaseTest { protected void openClientConnection() throws IOException { + openClientConnection(false); + } + + protected void openClientConnection(boolean tls) throws IOException { + SocketFactory socketFactory = tls ? TesterSupport.configureClientSsl() : SocketFactory.getDefault(); // Open a connection - s = SocketFactory.getDefault().createSocket("localhost", getPort()); + s = socketFactory.createSocket("localhost", getPort()); s.setSoTimeout(30000); os = s.getOutputStream(); @@ -609,6 +638,9 @@ public abstract class Http2TestBase extends TomcatBaseTest { boolean readHttpUpgradeResponse() throws IOException { String[] responseHeaders = readHttpResponseHeaders(); + for (String header : responseHeaders) { + System.out.println("HEADER: " + header); + } if (responseHeaders.length < 3) { return false; diff --git a/test/org/apache/coyote/http2/TestLargeUpload.java b/test/org/apache/coyote/http2/TestLargeUpload.java new file mode 100644 index 0000000..1e657af --- /dev/null +++ b/test/org/apache/coyote/http2/TestLargeUpload.java @@ -0,0 +1,112 @@ +/* + * 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.nio.ByteBuffer; +import java.util.concurrent.CountDownLatch; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.Context; +import org.apache.catalina.LifecycleException; +import org.apache.catalina.startup.Tomcat; +import org.apache.coyote.http11.AbstractHttp11Protocol; + +public class TestLargeUpload extends Http2TestBase { + + @Test + public void testLargePostRequest() throws Exception { + // FIXME: Skip test for now, some control flow errors with non async + org.junit.Assume.assumeFalse(true); + + http2Connect(true); + + ((AbstractHttp11Protocol<?>) http2Protocol.getHttp11Protocol()).setAllowedTrailerHeaders(TRAILER_HEADER_NAME); + + int bodySize = 16384; + int bodyCount = 20; + + byte[] headersFrameHeader = new byte[9]; + ByteBuffer headersPayload = ByteBuffer.allocate(128); + byte[] dataFrameHeader = new byte[9]; + ByteBuffer dataPayload = ByteBuffer.allocate(bodySize); + byte[] trailerFrameHeader = new byte[9]; + ByteBuffer trailerPayload = ByteBuffer.allocate(256); + + buildPostRequest(headersFrameHeader, headersPayload, false, dataFrameHeader, dataPayload, + null, trailerFrameHeader, trailerPayload, 3); + + // Write the headers + writeFrame(headersFrameHeader, headersPayload); + // Body + for (int i = 0; i < bodyCount; i++) { + writeFrame(dataFrameHeader, dataPayload); + } + + // Trailers + writeFrame(trailerFrameHeader, trailerPayload); + + done.await(); + Assert.assertEquals(Integer.valueOf(bodySize * bodyCount), Integer.valueOf(read)); + + } + + + @Override + protected void configureAndStartWebApplication() throws LifecycleException { + Tomcat tomcat = getTomcatInstance(); + + // Retain '/simple' url-pattern since it enables code re-use + Context ctxt = tomcat.addContext("", null); + Tomcat.addServlet(ctxt, "read", new DataReadServlet()); + ctxt.addServletMappingDecoded("/simple", "read"); + + tomcat.start(); + } + + volatile int read = 0; + CountDownLatch done = new CountDownLatch(1); + + private class DataReadServlet extends SimpleServlet { + + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + byte[] buf = new byte[8192]; + InputStream is = req.getInputStream(); + int n = is.read(buf); + while (n > 0) { + read += n; + n = is.read(buf); + } + done.countDown(); + if (read < 16384 * 20) { + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } else { + resp.setStatus(HttpServletResponse.SC_OK); + } + } + } +} diff --git a/test/org/apache/tomcat/util/net/TesterSupport.java b/test/org/apache/tomcat/util/net/TesterSupport.java index 829aa12..3f27bb5 100644 --- a/test/org/apache/tomcat/util/net/TesterSupport.java +++ b/test/org/apache/tomcat/util/net/TesterSupport.java @@ -194,7 +194,7 @@ public final class TesterSupport { return tmf.getTrustManagers(); } - protected static ClientSSLSocketFactory configureClientSsl() { + public static ClientSSLSocketFactory configureClientSsl() { ClientSSLSocketFactory clientSSLSocketFactory = null; try { SSLContext sc = SSLContext.getInstance(Constants.SSL_PROTO_TLS); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org