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 2012/02/25 17:47:27 UTC
svn commit: r1293647 - in /httpcomponents/httpcore/trunk: ./
httpcore-nio/src/main/java/org/apache/http/nio/protocol/
httpcore-nio/src/test/java/org/apache/http/nio/integration/
Author: olegk
Date: Sat Feb 25 16:47:26 2012
New Revision: 1293647
URL: http://svn.apache.org/viewvc?rev=1293647&view=rev
Log:
HTTPCORE-289: HttpAsyncService fails to invoke Cancellable#cancel() when the ongoing HTTP exchange is aborted by the client
Added:
httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java (with props)
Modified:
httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java
Modified: httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Sat Feb 25 16:47:26 2012
@@ -1,3 +1,11 @@
+Changes since 4.2-BETA1
+-------------------
+
+* [HTTPCORE-289] HttpAsyncService fails to invoke Cancellable#cancel() when the ongoing HTTP
+ exchange is aborted by the client.
+ Contributed by Oleg Kalnichevski <olegk at apache.org>
+
+
Release 4.2-BETA1
-------------------
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/protocol/HttpAsyncService.java Sat Feb 25 16:47:26 2012
@@ -356,12 +356,7 @@ public class HttpAsyncService implements
}
public void endOfInput(final NHttpServerConnection conn) throws IOException {
- State state = ensureNotNull(getState(conn));
- if (state.getResponseState().compareTo(MessageState.READY) > 0) {
- conn.suspendInput();
- } else {
- conn.close();
- }
+ conn.close();
}
public void timeout(final NHttpServerConnection conn) throws IOException {
Added: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java?rev=1293647&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java Sat Feb 25 16:47:26 2012
@@ -0,0 +1,153 @@
+/*
+ * ====================================================================
+ * 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.http.nio.integration;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.http.HttpCoreNIOTestBase;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.LoggingClientConnectionFactory;
+import org.apache.http.LoggingServerConnectionFactory;
+import org.apache.http.concurrent.Cancellable;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.impl.nio.DefaultNHttpServerConnection;
+import org.apache.http.nio.NHttpConnectionFactory;
+import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
+import org.apache.http.nio.protocol.HttpAsyncExchange;
+import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
+import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
+import org.apache.http.nio.protocol.HttpAsyncService;
+import org.apache.http.nio.reactor.IOReactorStatus;
+import org.apache.http.nio.reactor.ListenerEndpoint;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestHttpAsyncHandlerCancellable extends HttpCoreNIOTestBase {
+
+ @Before
+ public void setUp() throws Exception {
+ initServer();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ shutDownServer();
+ }
+
+ @Override
+ protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
+ final HttpParams params) throws Exception {
+ return new LoggingServerConnectionFactory(params);
+ }
+
+ @Override
+ protected NHttpConnectionFactory<DefaultNHttpClientConnection> createClientConnectionFactory(
+ final HttpParams params) throws Exception {
+ return new LoggingClientConnectionFactory(params);
+ }
+
+ @Test
+ public void testRequestCancelled() throws Exception {
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ final Cancellable cancellable = new Cancellable() {
+
+ public boolean cancel() {
+ latch.countDown();
+ return true;
+ }
+ };
+
+ HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
+ registry.register("*", new HttpAsyncRequestHandler<HttpRequest>() {
+
+ public HttpAsyncRequestConsumer<HttpRequest> processRequest(
+ final HttpRequest request,
+ final HttpContext context) throws HttpException, IOException {
+ return new BasicAsyncRequestConsumer();
+ }
+
+ public void handle(
+ final HttpRequest data,
+ final HttpAsyncExchange httpExchange,
+ final HttpContext context)
+ throws HttpException, IOException {
+ httpExchange.setCallback(cancellable);
+ // do not submit a response;
+ }
+
+ });
+ HttpAsyncService serviceHandler = new HttpAsyncService(
+ this.serverHttpProc,
+ new DefaultConnectionReuseStrategy(),
+ new DefaultHttpResponseFactory(),
+ registry,
+ null,
+ this.serverParams);
+ this.server.start(serviceHandler);
+
+ ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
+ InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+ Socket socket = new Socket("localhost", address.getPort());
+ try {
+ OutputStream outstream = socket.getOutputStream();
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
+ writer.write("GET /long HTTP/1.1\r\n");
+ writer.write("Host: localhost\r\n");
+ writer.write("\r\n");
+ writer.flush();
+
+ Thread.sleep(250);
+
+ writer.close();
+ } finally {
+ socket.close();
+ }
+
+ Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
+ }
+
+}
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlerCancellable.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlers.java Sat Feb 25 16:47:26 2012
@@ -54,17 +54,17 @@ import org.apache.http.message.BasicHttp
import org.apache.http.nio.NHttpConnectionFactory;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
+import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
import org.apache.http.nio.protocol.BasicAsyncRequestProducer;
import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
-import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
-import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
+import org.apache.http.nio.protocol.HttpAsyncExchange;
import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
+import org.apache.http.nio.protocol.HttpAsyncRequestExecutor;
import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
import org.apache.http.nio.protocol.HttpAsyncRequestHandlerRegistry;
import org.apache.http.nio.protocol.HttpAsyncRequestHandlerResolver;
-import org.apache.http.nio.protocol.HttpAsyncExchange;
import org.apache.http.nio.protocol.HttpAsyncService;
import org.apache.http.nio.reactor.IOReactorStatus;
import org.apache.http.nio.reactor.ListenerEndpoint;
Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java?rev=1293647&r1=1293646&r2=1293647&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestPipelining.java Sat Feb 25 16:47:26 2012
@@ -36,6 +36,8 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import org.apache.http.HttpCoreNIOTestBase;
import org.apache.http.HttpException;
@@ -71,7 +73,6 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mockito;
/**
* Tests for handling pipelined requests.
@@ -178,80 +179,16 @@ public class TestPipelining extends Http
}
@Test
- public void testBasicPipeliningHalfClosed() throws Exception {
- HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
- registry.register("*", new BasicAsyncRequestHandler(new HttpRequestHandler() {
-
- public void handle(
- final HttpRequest request,
- final HttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- String content = "thank you very much";
- NStringEntity entity = NStringEntity.create(content, ContentType.DEFAULT_TEXT);
- response.setEntity(entity);
- }
-
- }));
- HttpAsyncService serviceHandler = new HttpAsyncService(
- this.serverHttpProc,
- new DefaultConnectionReuseStrategy(),
- registry,
- this.serverParams);
- this.server.start(serviceHandler);
-
- ListenerEndpoint endpoint = this.server.getListenerEndpoint();
- endpoint.waitFor();
-
- Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
-
- InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
- Socket socket = new Socket("localhost", address.getPort());
- try {
- OutputStream outstream = socket.getOutputStream();
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outstream, "US-ASCII"));
- writer.write("GET / HTTP/1.1\r\n");
- writer.write("Host: localhost\r\n");
- writer.write("\r\n");
- writer.write("GET / HTTP/1.1\r\n");
- writer.write("Host: localhost\r\n");
- writer.write("\r\n");
- writer.flush();
- socket.shutdownOutput();
- InputStream instream = socket.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(instream, "US-ASCII"));
- StringBuilder buf = new StringBuilder();
- char[] tmp = new char[1024];
- int l;
- while ((l = reader.read(tmp)) != -1) {
- buf.append(tmp, 0, l);
- }
- reader.close();
- writer.close();
- String expected =
- "HTTP/1.1 200 OK\r\n" +
- "Server: TEST-SERVER/1.1\r\n" +
- "Content-Length: 19\r\n" +
- "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
- "\r\n" +
- "thank you very much" +
- "HTTP/1.1 200 OK\r\n" +
- "Server: TEST-SERVER/1.1\r\n" +
- "Content-Length: 19\r\n" +
- "Content-Type: text/plain; charset=ISO-8859-1\r\n" +
- "\r\n" +
- "thank you very much";
- Assert.assertEquals(expected, buf.toString());
-
- } finally {
- socket.close();
- }
-
- }
-
- @Test
public void testPipeliningWithCancellable() throws Exception {
- final Cancellable cancellable = Mockito.mock(Cancellable.class);
+ final CountDownLatch latch = new CountDownLatch(1);
+ final Cancellable cancellable = new Cancellable() {
+
+ public boolean cancel() {
+ latch.countDown();
+ return true;
+ }
+ };
HttpAsyncRequestHandlerRegistry registry = new HttpAsyncRequestHandlerRegistry();
registry.register("/long", new HttpAsyncRequestHandler<HttpRequest>() {
@@ -332,7 +269,7 @@ public class TestPipelining extends Http
socket.close();
}
- Mockito.verify(cancellable).cancel();
+ Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
}