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 2008/03/11 20:13:03 UTC
svn commit: r636066 - in /httpcomponents/httpcore/trunk/module-nio/src:
main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java
Author: olegk
Date: Tue Mar 11 12:12:55 2008
New Revision: 636066
URL: http://svn.apache.org/viewvc?rev=636066&view=rev
Log:
Fixed bug in NHttpEntityWrapper causing infinite loop in the async protocol handlers
Modified:
httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java
Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java?rev=636066&r1=636065&r2=636066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java Tue Mar 11 12:12:55 2008
@@ -77,8 +77,9 @@
int i = this.channel.read(this.buffer);
this.buffer.flip();
encoder.write(this.buffer);
+ boolean buffering = this.buffer.hasRemaining();
this.buffer.compact();
- if (i == -1 && !this.buffer.hasRemaining()) {
+ if (i == -1 && !buffering) {
encoder.complete();
this.channel.close();
}
Modified: httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java?rev=636066&r1=636065&r2=636066&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java Tue Mar 11 12:12:55 2008
@@ -47,6 +47,8 @@
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.mockup.ByteSequence;
@@ -56,6 +58,7 @@
import org.apache.http.nio.NHttpConnection;
import org.apache.http.nio.NHttpServiceHandler;
import org.apache.http.nio.entity.NByteArrayEntity;
+import org.apache.http.nio.entity.NHttpEntityWrapper;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
import org.apache.http.nio.reactor.ListenerEndpoint;
@@ -649,4 +652,146 @@
}
+ /**
+ * This test case executes a series of simple (non-pipelined) POST requests
+ * with chunk coded content over multiple connections using
+ * {@link NHttpEntityWrapper}.
+ */
+ public void testSimpleBasicHttpEntityEnclosingRequestsChunkedWithWrapper() throws Exception {
+
+ final int connNo = 1;
+ final int reqNo = 2;
+ final RequestCount requestCount = new RequestCount(connNo * reqNo);
+
+ final ByteSequence requestData = new ByteSequence();
+ requestData.rnd(reqNo);
+
+ List<ByteSequence> responseData = new ArrayList<ByteSequence>(connNo);
+ for (int i = 0; i < connNo; i++) {
+ responseData.add(new ByteSequence());
+ }
+
+ HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+
+ if (request instanceof HttpEntityEnclosingRequest) {
+ HttpEntity incoming = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] data = EntityUtils.toByteArray(incoming);
+ ByteArrayEntity outgoing = new ByteArrayEntity(data);
+ outgoing.setChunked(true);
+ response.setEntity(new NHttpEntityWrapper(outgoing));
+ } else {
+ StringEntity outgoing = new StringEntity("No content");
+ response.setEntity(new NHttpEntityWrapper(outgoing));
+ }
+ }
+
+ };
+
+ HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
+
+ public void initalizeContext(final HttpContext context, final Object attachment) {
+ context.setAttribute("LIST", (ByteSequence) attachment);
+ context.setAttribute("REQ-COUNT", new Integer(0));
+ context.setAttribute("RES-COUNT", new Integer(0));
+ }
+
+ public void finalizeContext(final HttpContext context) {
+ }
+
+ public HttpRequest submitRequest(final HttpContext context) {
+ int i = ((Integer) context.getAttribute("REQ-COUNT")).intValue();
+ BasicHttpEntityEnclosingRequest post = null;
+ if (i < reqNo) {
+ post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
+ byte[] bytes = requestData.getBytes(i);
+ ByteArrayEntity outgoing = new ByteArrayEntity(bytes);
+ outgoing.setChunked(true);
+ post.setEntity(outgoing);
+
+ context.setAttribute("REQ-COUNT", new Integer(i + 1));
+ }
+ return post;
+ }
+
+ public void handleResponse(final HttpResponse response, final HttpContext context) {
+ NHttpConnection conn = (NHttpConnection) context.getAttribute(
+ ExecutionContext.HTTP_CONNECTION);
+
+ ByteSequence list = (ByteSequence) context.getAttribute("LIST");
+ int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
+ i++;
+ context.setAttribute("RES-COUNT", new Integer(i));
+
+ try {
+ HttpEntity entity = response.getEntity();
+ byte[] data = EntityUtils.toByteArray(entity);
+ list.addBytes(data);
+ requestCount.decrement();
+ } catch (IOException ex) {
+ requestCount.abort();
+ }
+
+ if (i < reqNo) {
+ conn.requestInput();
+ }
+ }
+
+ };
+
+ SimpleEventListener serverEventListener = new SimpleEventListener();
+ SimpleEventListener clientEventListener = new SimpleEventListener();
+
+ NHttpServiceHandler serviceHandler = createHttpServiceHandler(
+ requestHandler,
+ null,
+ serverEventListener);
+
+ NHttpClientHandler clientHandler = createHttpClientHandler(
+ requestExecutionHandler,
+ clientEventListener);
+
+ this.server.setRequestCount(requestCount);
+ this.client.setRequestCount(requestCount);
+
+ this.server.start(serviceHandler);
+ this.client.start(clientHandler);
+
+ ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+ InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
+
+ for (int i = 0; i < responseData.size(); i++) {
+ this.client.openConnection(
+ new InetSocketAddress("localhost", serverAddress.getPort()),
+ responseData.get(i));
+ }
+
+ requestCount.await(10000);
+ assertEquals(0, requestCount.getValue());
+
+ this.client.shutdown();
+ this.server.shutdown();
+
+ for (int c = 0; c < responseData.size(); c++) {
+ ByteSequence receivedPackets = responseData.get(c);
+ ByteSequence expectedPackets = requestData;
+ assertEquals(expectedPackets.size(), receivedPackets.size());
+ for (int p = 0; p < requestData.size(); p++) {
+ byte[] expected = requestData.getBytes(p);
+ byte[] received = receivedPackets.getBytes(p);
+
+ assertEquals(expected.length, received.length);
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], received[i]);
+ }
+ }
+ }
+
+ }
+
}