hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1773436 - in /httpcomponents/httpcore/trunk: ./ httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ httpcore5-testing-compat/ httpcore5-testing-compat/src/ httpcore5-testing-compat/src/test/ httpcore5-testing-compat/src/test/jav...
Date Fri, 09 Dec 2016 16:48:15 GMT
Author: olegk
Date: Fri Dec  9 16:48:14 2016
New Revision: 1773436

URL: http://svn.apache.org/viewvc?rev=1773436&view=rev
Log:
Jetty Server compatibility tests

Added:
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml   (with props)
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
  (with props)
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
  (with props)
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
  (with props)
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2-debug.xml.template
    httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml 
 (with props)
Modified:
    httpcomponents/httpcore/trunk/.gitignore
    httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java
    httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/http2/Http2IntegrationTest.java
    httpcomponents/httpcore/trunk/pom.xml

Modified: httpcomponents/httpcore/trunk/.gitignore
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/.gitignore?rev=1773436&r1=1773435&r2=1773436&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/.gitignore (original)
+++ httpcomponents/httpcore/trunk/.gitignore Fri Dec  9 16:48:14 2016
@@ -7,4 +7,4 @@ target
 maven-eclipse.xml
 .idea
 *.iml
-/httpcore5-testing/src/test/resources/log4j2-debug.xml
+**/log4j2-debug.xml

Modified: httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java?rev=1773436&r1=1773435&r2=1773436&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java
Fri Dec  9 16:48:14 2016
@@ -753,16 +753,21 @@ abstract class AbstractHttp2StreamMultip
                 if (streamId == 0) {
                     throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, "Illegal stream
id: " + streamId);
                 }
-                final Http2Stream stream = getValidStream(streamId);
-                final ByteBuffer payload = frame.getPayload();
-                if (payload == null || payload.remaining() != 4) {
-                    throw new H2ConnectionException(H2Error.FRAME_SIZE_ERROR, "Invalid RST_STREAM
frame payload");
+                final Http2Stream stream = streamMap.get(streamId);
+                if (stream == null) {
+                    if (streamId > lastStreamId.get()) {
+                        throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, "Unexpected
stream id: " + streamId);
+                    }
+                } else {
+                    final ByteBuffer payload = frame.getPayload();
+                    if (payload == null || payload.remaining() != 4) {
+                        throw new H2ConnectionException(H2Error.FRAME_SIZE_ERROR, "Invalid
RST_STREAM frame payload");
+                    }
+                    final int errorCode = payload.getInt();
+                    stream.reset(new H2StreamResetException(errorCode, "Stream reset"));
+                    streamMap.remove(streamId);
+                    stream.releaseResources();
                 }
-
-                final int errorCode = payload.getInt();
-                stream.reset(new H2StreamResetException(errorCode, "Stream reset"));
-                streamMap.remove(streamId);
-                stream.releaseResources();
             }
             break;
             case PING: {

Added: httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml?rev=1773436&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml Fri Dec  9 16:48:14 2016
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   ====================================================================
+   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.
+   ====================================================================
+
+   This software consists of voluntary contributions made by many
+   individuals on behalf of the Apache Software Foundation.  For more
+   information on the Apache Software Foundation, please see
+   <http://www.apache.org />.
+ --><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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.httpcomponents.core5</groupId>
+    <artifactId>httpcore5-parent</artifactId>
+    <version>5.0-alpha2-SNAPSHOT</version>
+  </parent>
+  <artifactId>httpcore5-testing-compat</artifactId>
+  <name>Apache HttpComponents Core Compatibility Tests</name>
+  <description>Apache HttpComponents HTTP/2 and HTTP/1.1 core component compatibility
tests</description>
+  <url>http://hc.apache.org/httpcomponents-core-ga</url>
+  <packaging>jar</packaging>
+
+  <properties>
+    <jetty.version>9.3.14.v20161028</jetty.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.httpcomponents.core5</groupId>
+      <artifactId>httpcore5-testing</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-server</artifactId>
+      <version>${jetty.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty.http2</groupId>
+      <artifactId>http2-server</artifactId>
+      <version>${jetty.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <reporting>
+    <plugins>
+
+      <plugin>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>${hc.project-info.version}</version>
+        <inherited>false</inherited>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>dependencies</report>
+              <report>dependency-info</report>
+              <report>summary</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+
+    </plugins>
+  </reporting>
+
+</project>

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java?rev=1773436&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
(added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
Fri Dec  9 16:48:14 2016
@@ -0,0 +1,113 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.compatibility.http2;
+
+import org.apache.logging.log4j.LogManager;
+import org.eclipse.jetty.util.log.AbstractLogger;
+import org.eclipse.jetty.util.log.Logger;
+
+class InternalJettyLogger extends AbstractLogger {
+
+    private final String name;
+    private final org.apache.logging.log4j.Logger logger;
+
+    InternalJettyLogger(final String name) {
+        this.name = name;
+        this.logger = LogManager.getLogger(name);
+    }
+
+    @Override
+    protected Logger newLogger(final String fullname) {
+        return new InternalJettyLogger(fullname);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void warn(final String msg, final Object... args) {
+        logger.warn(msg, args);
+    }
+
+    @Override
+    public void warn(final Throwable thrown) {
+        logger.warn(thrown);
+    }
+
+    @Override
+    public void warn(final String msg, final Throwable thrown) {
+        logger.warn(msg, thrown);
+    }
+
+    @Override
+    public void info(final String msg, final Object... args) {
+        logger.info(msg, args);
+    }
+
+    @Override
+    public void info(final Throwable thrown) {
+        logger.info(thrown);
+    }
+
+    @Override
+    public void info(final String msg, final Throwable thrown) {
+        logger.info(msg, thrown);
+    }
+
+    @Override
+    public boolean isDebugEnabled() {
+        return logger.isDebugEnabled();
+    }
+
+    @Override
+    public void setDebugEnabled(final boolean enabled) {
+    }
+
+    @Override
+    public void debug(final String msg, final Object... args) {
+        logger.debug(msg, args);
+    }
+
+    @Override
+    public void debug(final Throwable thrown) {
+        logger.debug(thrown);
+    }
+
+    @Override
+    public void debug(final String msg, final Throwable thrown) {
+        logger.debug(msg, thrown);
+    }
+
+    @Override
+    public void ignore(final Throwable ignored) {
+        logger.trace(ignored);
+    }
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/InternalJettyLogger.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java?rev=1773436&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
(added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
Fri Dec  9 16:48:14 2016
@@ -0,0 +1,401 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.compatibility.http2;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.StringTokenizer;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.impl.nio.bootstrap.ClientEndpoint;
+import org.apache.hc.core5.http.impl.nio.entity.AbstractClassicEntityConsumer;
+import org.apache.hc.core5.http.impl.nio.entity.AbstractClassicEntityProducer;
+import org.apache.hc.core5.http.message.BasicHttpRequest;
+import org.apache.hc.core5.http.nio.BasicRequestProducer;
+import org.apache.hc.core5.http.nio.BasicResponseConsumer;
+import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
+import org.apache.hc.core5.http2.config.H2Config;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.testing.nio.http2.Http2TestClient;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JettyHttp2CompatibilityTest extends JettyServerTestBase {
+
+    private static final long TIMEOUT = 5;
+
+    private Http2TestClient client;
+
+    @Before
+    public void setup() throws Exception {
+        client = new Http2TestClient(IOReactorConfig.DEFAULT, null);
+    }
+
+    @After
+    public void cleanup() throws Exception {
+        if (client != null) {
+            client.shutdown(3, TimeUnit.SECONDS);
+        }
+    }
+
+    private URI createRequestURI(final URI serverEndpoint, final String path) throws URISyntaxException
{
+        return new URI(serverEndpoint.getScheme(), serverEndpoint.getAuthority(), path, null,
null);
+    }
+
+    static class SingleLineResponseHandler extends AbstractHandler {
+
+        private final String message;
+
+        SingleLineResponseHandler(final String message) {
+            this.message = message;
+        }
+
+        @Override
+        public void handle(
+                final String target,
+                final Request baseRequest,
+                final HttpServletRequest request,
+                final HttpServletResponse response) throws IOException, ServletException
{
+            response.setContentType("text/html; charset=utf-8");
+            response.setStatus(HttpServletResponse.SC_OK);
+            final PrintWriter out = response.getWriter();
+            out.print(message);
+            out.flush();
+            baseRequest.setHandled(true);
+        }
+
+    }
+
+    @Test
+    public void testSimpleGet() throws Exception {
+        final ContextHandler contextHandler = new ContextHandler();
+        contextHandler.setHandler(new SingleLineResponseHandler("Hi there"));
+        server.setHandler(contextHandler);
+        server.start();
+
+        final URI serverEndpoint = server.getURI();
+
+        client.start();
+        final Future<ClientEndpoint> connectFuture = client.connect(
+                "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
+        final ClientEndpoint streamEndpoint = connectFuture.get();
+
+        final Queue<Future<Message<HttpResponse, String>>> queue = new
LinkedList<>();
+        for (int i = 0; i < 10; i++) {
+            queue.add(streamEndpoint.execute(
+                    new BasicRequestProducer("GET", createRequestURI(serverEndpoint, "/hello")),
+                    new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
+
+        }
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, String>> future = queue.remove();
+            final Message<HttpResponse, String> result = future.get(TIMEOUT, TimeUnit.SECONDS);
+            Assert.assertNotNull(result);
+            final HttpResponse response = result.getHead();
+            final String entity = result.getBody();
+            Assert.assertNotNull(response);
+            Assert.assertEquals(200, response.getCode());
+            Assert.assertEquals("Hi there", entity);
+        }
+    }
+
+    static class MultiLineResponseHandler extends AbstractHandler {
+
+        private final String message;
+        private final int count;
+
+        MultiLineResponseHandler(final String message, final int count) {
+            this.message = message;
+            this.count = count;
+        }
+
+        @Override
+        public void handle(
+                final String target,
+                final Request baseRequest,
+                final HttpServletRequest request,
+                final HttpServletResponse response) throws IOException, ServletException
{
+            response.setContentType("text/html; charset=utf-8");
+            response.setStatus(HttpServletResponse.SC_OK);
+            final PrintWriter out = response.getWriter();
+            for (int i = 0; i < count; i++) {
+                out.println(message);
+            }
+            out.flush();
+            baseRequest.setHandled(true);
+        }
+
+    }
+
+    @Test
+    public void testLargeGet() throws Exception {
+        final ContextHandler contextHandler = new ContextHandler();
+        contextHandler.setHandler(new MultiLineResponseHandler("0123456789abcdef", 5000));
+        server.setHandler(contextHandler);
+        server.start();
+
+        final URI serverEndpoint = server.getURI();
+
+        client.start();
+        final Future<ClientEndpoint> connectFuture = client.connect(
+                "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
+        final ClientEndpoint streamEndpoint = connectFuture.get();
+
+        final HttpRequest request1 = new BasicHttpRequest("GET", createRequestURI(serverEndpoint,
"/"));
+        final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
+                new BasicRequestProducer(request1, null),
+                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+
+        final HttpRequest request2 = new BasicHttpRequest("GET", createRequestURI(serverEndpoint,
"/"));
+        final Future<Message<HttpResponse, String>> future2 = streamEndpoint.execute(
+                new BasicRequestProducer(request2, null),
+                new BasicResponseConsumer<>(new StringAsyncEntityConsumer(512)), null);
+
+        final Message<HttpResponse, String> result1 = future1.get();
+        Assert.assertNotNull(result1);
+        final HttpResponse response1 = result1.getHead();
+        Assert.assertNotNull(response1);
+        Assert.assertEquals(200, response1.getCode());
+        final String s1 = result1.getBody();
+        Assert.assertNotNull(s1);
+        final StringTokenizer t1 = new StringTokenizer(s1, "\r\n");
+        while (t1.hasMoreTokens()) {
+            Assert.assertEquals("0123456789abcdef", t1.nextToken());
+        }
+
+        final Message<HttpResponse, String> result2 = future2.get();
+        Assert.assertNotNull(result2);
+        final HttpResponse response2 = result2.getHead();
+        Assert.assertNotNull(response2);
+        Assert.assertEquals(200, response2.getCode());
+        final String s2 = result2.getBody();
+        Assert.assertNotNull(s2);
+        final StringTokenizer t2 = new StringTokenizer(s2, "\r\n");
+        while (t2.hasMoreTokens()) {
+            Assert.assertEquals("0123456789abcdef", t2.nextToken());
+        }
+    }
+
+    @Test
+    public void testBasicPost() throws Exception {
+        final ContextHandler contextHandler = new ContextHandler();
+        contextHandler.setHandler(new SingleLineResponseHandler("Hi back"));
+        server.setHandler(contextHandler);
+        server.start();
+
+        final URI serverEndpoint = server.getURI();
+
+        client.start();
+        final Future<ClientEndpoint> connectFuture = client.connect(
+                "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
+        final ClientEndpoint streamEndpoint = connectFuture.get();
+
+        final Queue<Future<Message<HttpResponse, String>>> queue = new
LinkedList<>();
+        for (int i = 0; i < 10; i++) {
+            final HttpRequest request = new BasicHttpRequest("POST", createRequestURI(serverEndpoint,
"/hello"));
+            queue.add(streamEndpoint.execute(
+                    new BasicRequestProducer(request, new StringAsyncEntityProducer("Hi there",
ContentType.TEXT_PLAIN)),
+                    new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
+
+        }
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, String>> future = queue.remove();
+            final Message<HttpResponse, String> result = future.get(TIMEOUT, TimeUnit.SECONDS);
+            Assert.assertNotNull(result);
+            final HttpResponse response = result.getHead();
+            final String entity1 = result.getBody();
+            Assert.assertNotNull(response);
+            Assert.assertEquals(200, response.getCode());
+            Assert.assertEquals("Hi back", entity1);
+        }
+    }
+
+    static class EchoHandler extends AbstractHandler {
+
+        @Override
+        public void handle(
+                final String target,
+                final Request baseRequest,
+                final HttpServletRequest request,
+                final HttpServletResponse response) throws IOException, ServletException
{
+
+            response.setContentType("text/html; charset=utf-8");
+            response.setStatus(HttpServletResponse.SC_OK);
+
+            final BufferedReader reader = request.getReader();
+            final PrintWriter out = response.getWriter();
+            String line;
+            while ((line = reader.readLine()) != null) {
+                out.println(line);
+            }
+            out.flush();
+            baseRequest.setHandled(true);
+        }
+
+    }
+
+    @Test
+    public void testSlowResponseConsumer() throws Exception {
+        final ContextHandler contextHandler = new ContextHandler();
+        contextHandler.setHandler(new MultiLineResponseHandler("0123456789abcdef", 3));
+        server.setHandler(contextHandler);
+        server.start();
+
+        final URI serverEndpoint = server.getURI();
+
+        client = new Http2TestClient();
+        client.start(H2Config.custom().setInitialWindowSize(16).build());
+        final Future<ClientEndpoint> connectFuture = client.connect(
+                "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
+        final ClientEndpoint streamEndpoint = connectFuture.get();
+
+        final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
+                new BasicRequestProducer("GET", createRequestURI(serverEndpoint, "/"), null),
+                new BasicResponseConsumer<>(new AbstractClassicEntityConsumer<String>(16,
Executors.newSingleThreadExecutor()) {
+
+                    @Override
+                    protected String consumeData(
+                            final ContentType contentType, final InputStream inputStream)
throws IOException {
+                        Charset charset = contentType != null ? contentType.getCharset()
: null;
+                        if (charset == null) {
+                            charset = StandardCharsets.US_ASCII;
+                        }
+
+                        final StringBuilder buffer = new StringBuilder();
+                        try {
+                            final byte[] tmp = new byte[16];
+                            int l;
+                            while ((l = inputStream.read(tmp)) != -1) {
+                                buffer.append(charset.decode(ByteBuffer.wrap(tmp, 0, l)));
+                                Thread.sleep(500);
+                            }
+                        } catch (InterruptedException ex) {
+                            Thread.currentThread().interrupt();
+                            throw new InterruptedIOException(ex.getMessage());
+                        }
+                        return buffer.toString();
+                    }
+                }),
+                null);
+
+        final Message<HttpResponse, String> result1 = future1.get(TIMEOUT, TimeUnit.SECONDS);
+        Assert.assertNotNull(result1);
+        final HttpResponse response1 = result1.getHead();
+        Assert.assertNotNull(response1);
+        Assert.assertEquals(200, response1.getCode());
+        final String s1 = result1.getBody();
+        Assert.assertNotNull(s1);
+        final StringTokenizer t1 = new StringTokenizer(s1, "\r\n");
+        while (t1.hasMoreTokens()) {
+            Assert.assertEquals("0123456789abcdef", t1.nextToken());
+        }
+    }
+
+    @Test
+    public void testSlowRequestProducer() throws Exception {
+        final ContextHandler contextHandler = new ContextHandler();
+        contextHandler.setHandler(new EchoHandler());
+        server.setHandler(contextHandler);
+        server.start();
+
+        final URI serverEndpoint = server.getURI();
+
+        client.start();
+        final Future<ClientEndpoint> connectFuture = client.connect(
+                "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
+        final ClientEndpoint streamEndpoint = connectFuture.get();
+
+        final HttpRequest request1 = new BasicHttpRequest("POST", createRequestURI(serverEndpoint,
"/echo"));
+        final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
+                new BasicRequestProducer(request1, new AbstractClassicEntityProducer(4096,
ContentType.TEXT_PLAIN, Executors.newSingleThreadExecutor()) {
+
+                    @Override
+                    protected void produceData(final ContentType contentType, final OutputStream
outputStream) throws IOException {
+                        Charset charset = contentType.getCharset();
+                        if (charset == null) {
+                            charset = StandardCharsets.US_ASCII;
+                        }
+                        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream,
charset))) {
+                            for (int i = 0; i < 500; i++) {
+                                if (i % 100 == 0) {
+                                    writer.flush();
+                                    Thread.sleep(500);
+                                }
+                                writer.write("0123456789abcdef\r\n");
+                            }
+                        } catch (InterruptedException ex) {
+                            Thread.currentThread().interrupt();
+                            throw new InterruptedIOException(ex.getMessage());
+                        }
+                    }
+
+                }),
+                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
+        final Message<HttpResponse, String> result1 = future1.get();
+        Assert.assertNotNull(result1);
+        final HttpResponse response1 = result1.getHead();
+        Assert.assertNotNull(response1);
+        Assert.assertEquals(200, response1.getCode());
+        final String s1 = result1.getBody();
+        Assert.assertNotNull(s1);
+        final StringTokenizer t1 = new StringTokenizer(s1, "\r\n");
+        while (t1.hasMoreTokens()) {
+            Assert.assertEquals("0123456789abcdef", t1.nextToken());
+        };
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyHttp2CompatibilityTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java?rev=1773436&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
(added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
Fri Dec  9 16:48:14 2016
@@ -0,0 +1,71 @@
+/*
+ * ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.compatibility.http2;
+
+import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.junit.Rule;
+import org.junit.rules.ExternalResource;
+
+public abstract class JettyServerTestBase {
+
+    static {
+        org.eclipse.jetty.util.log.Log.setLog(new InternalJettyLogger("root"));
+    }
+
+    protected Server server;
+
+    @Rule
+    public ExternalResource serverResource = new ExternalResource() {
+
+        @Override
+        protected void before() throws Throwable {
+            server = new Server();
+            final HttpConfiguration httpConfig = new HttpConfiguration();
+            final ServerConnector serverConnector = new ServerConnector(server, new HTTP2CServerConnectionFactory(httpConfig));
+            serverConnector.setPort(0);
+            serverConnector.setIdleTimeout(0);
+            server.addConnector(serverConnector);
+        }
+
+        @Override
+        protected void after() {
+            if (server != null) {
+                try {
+                    server.stop();
+                    server = null;
+                } catch (Exception ignore) {
+                }
+            }
+        }
+
+    };
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/java/org/apache/hc/core5/compatibility/http2/JettyServerTestBase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2-debug.xml.template
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2-debug.xml.template?rev=1773436&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2-debug.xml.template
(added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2-debug.xml.template
Fri Dec  9 16:48:14 2016
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<Configuration status="WARN" name="XMLConfigTest">
+    <Appenders>
+        <Console name="STDOUT">
+            <PatternLayout pattern="%d %-5level [%t][%logger]%notEmpty{[%markerSimpleName]}
%msg%n%xThrowable"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="warn">
+            <AppenderRef ref="STDOUT"/>
+        </Root>
+        <Logger name="org.apache.hc.core5.reactor" level="debug"/>
+        <Logger name="org.apache.hc.core5.http.headers" level="debug"/>
+        <Logger name="org.apache.hc.core5.http.wire" level="error"/>
+        <Logger name="org.apache.hc.core5.http2.frame" level="debug"/>
+        <Logger name="org.apache.hc.core5.http2.frame.payload" level="error"/>
+        <Logger name="org.apache.hc.core5.http2.flow" level="debug"/>
+    </Loggers>
+</Configuration>
\ No newline at end of file

Added: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml?rev=1773436&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml (added)
+++ httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml Fri
Dec  9 16:48:14 2016
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<Configuration status="WARN" name="XMLConfigTest">
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%d %-5level [%t][%logger]%notEmpty{[%markerSimpleName]}
%msg%n%xThrowable" />
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="fatal">
+      <AppenderRef ref="STDOUT" />
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore5-testing-compat/src/test/resources/log4j2.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Modified: httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/http2/Http2IntegrationTest.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/http2/Http2IntegrationTest.java?rev=1773436&r1=1773435&r2=1773436&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/http2/Http2IntegrationTest.java
(original)
+++ httpcomponents/httpcore/trunk/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/http2/Http2IntegrationTest.java
Fri Dec  9 16:48:14 2016
@@ -169,16 +169,23 @@ public class Http2IntegrationTest extend
                 "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
         final ClientEndpoint streamEndpoint = connectFuture.get();
 
-        final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
-                new BasicRequestProducer("GET", createRequestURI(serverEndpoint, "/hello")),
-                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
-        final Message<HttpResponse, String> result1 = future1.get(TIMEOUT, TimeUnit.SECONDS);
-        Assert.assertNotNull(result1);
-        final HttpResponse response1 = result1.getHead();
-        final String entity1 = result1.getBody();
-        Assert.assertNotNull(response1);
-        Assert.assertEquals(200, response1.getCode());
-        Assert.assertEquals("Hi there", entity1);
+        final Queue<Future<Message<HttpResponse, String>>> queue = new
LinkedList<>();
+        for (int i = 0; i < 10; i++) {
+            queue.add(streamEndpoint.execute(
+                    new BasicRequestProducer("GET", createRequestURI(serverEndpoint, "/hello")),
+                    new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
+
+        }
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, String>> future = queue.remove();
+            final Message<HttpResponse, String> result = future.get(TIMEOUT, TimeUnit.SECONDS);
+            Assert.assertNotNull(result);
+            final HttpResponse response = result.getHead();
+            final String entity = result.getBody();
+            Assert.assertNotNull(response);
+            Assert.assertEquals(200, response.getCode());
+            Assert.assertEquals("Hi there", entity);
+        }
     }
 
     @Test
@@ -248,17 +255,24 @@ public class Http2IntegrationTest extend
                 "localhost", serverEndpoint.getPort(), TIMEOUT, TimeUnit.SECONDS);
         final ClientEndpoint streamEndpoint = connectFuture.get();
 
-        final HttpRequest request1 = new BasicHttpRequest("POST", createRequestURI(serverEndpoint,
"/hello"));
-        final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
-                new BasicRequestProducer(request1, new BasicAsyncEntityProducer("Hi there")),
-                new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
-        final Message<HttpResponse, String> result1 = future1.get(TIMEOUT, TimeUnit.SECONDS);
-        Assert.assertNotNull(result1);
-        final HttpResponse response1 = result1.getHead();
-        final String entity1 = result1.getBody();
-        Assert.assertNotNull(response1);
-        Assert.assertEquals(200, response1.getCode());
-        Assert.assertEquals("Hi back", entity1);
+        final Queue<Future<Message<HttpResponse, String>>> queue = new
LinkedList<>();
+        for (int i = 0; i < 10; i++) {
+            final HttpRequest request = new BasicHttpRequest("POST", createRequestURI(serverEndpoint,
"/hello"));
+            queue.add(streamEndpoint.execute(
+                    new BasicRequestProducer(request, new StringAsyncEntityProducer("Hi there",
ContentType.TEXT_PLAIN)),
+                    new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null));
+
+        }
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, String>> future = queue.remove();
+            final Message<HttpResponse, String> result = future.get(TIMEOUT, TimeUnit.SECONDS);
+            Assert.assertNotNull(result);
+            final HttpResponse response = result.getHead();
+            final String entity1 = result.getBody();
+            Assert.assertNotNull(response);
+            Assert.assertEquals(200, response.getCode());
+            Assert.assertEquals("Hi back", entity1);
+        }
     }
 
     @Test

Modified: httpcomponents/httpcore/trunk/pom.xml
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/pom.xml?rev=1773436&r1=1773435&r2=1773436&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/pom.xml (original)
+++ httpcomponents/httpcore/trunk/pom.xml Fri Dec  9 16:48:14 2016
@@ -69,8 +69,8 @@
     <module>httpcore5</module>
     <module>httpcore5-h2</module>
     <module>httpcore5-ab</module>
-    <module>httpcore5-testing</module>
     <module>httpcore5-osgi</module>
+    <module>httpcore5-testing</module>
   </modules>
 
   <properties>
@@ -354,4 +354,16 @@
     </plugins>
   </reporting>
 
+  <profiles>
+    <profile>
+      <id>compat-tests</id>
+      <modules>
+        <module>httpcore5-testing-compat</module>
+      </modules>
+      <activation>
+        <jdk>1.8</jdk>
+      </activation>
+    </profile>
+  </profiles>
+
 </project>




Mime
View raw message