You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2016/12/09 16:48:15 UTC
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...
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>