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/02 13:23:04 UTC

svn commit: r632746 - in /httpcomponents/httpcore/trunk/module-nio/src: examples/org/apache/http/examples/nio/ main/java/org/apache/http/nio/entity/ main/java/org/apache/http/nio/protocol/ test/java/org/apache/http/nio/protocol/

Author: olegk
Date: Sun Mar  2 04:23:03 2008
New Revision: 632746

URL: http://svn.apache.org/viewvc?rev=632746&view=rev
Log:
Rewrite of BufferingHttpServiceHandler as a decorator for NHttpAsyncServiceHandler

Added:
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java   (with props)
Modified:
    httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpFileServer.java
    httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
    httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/NHttpClientHandlerBase.java
    httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestBufferingNHttpHandlers.java

Modified: httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpFileServer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpFileServer.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpFileServer.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpFileServer.java Sun Mar  2 04:23:03 2008
@@ -165,13 +165,17 @@
             final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8"));
             if (!file.exists()) {
                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
-                NStringEntity entity = new NStringEntity("<html><body><h1>File" +
-                        file.getPath() + " not found</h1></body></html>", "UTF-8");
+                NStringEntity entity = new NStringEntity(
+                        "<html><body><h1>File" + file.getPath() +
+                        " not found</h1></body></html>",
+                        "UTF-8");
                 entity.setContentType("text/html; charset=UTF-8");
                 response.setEntity(entity);
             } else if (!file.canRead() || file.isDirectory()) {
                 response.setStatusCode(HttpStatus.SC_FORBIDDEN);
-                NStringEntity entity = new NStringEntity("<html><body><h1>Access denied</h1></body></html>", "UTF-8");
+                NStringEntity entity = new NStringEntity(
+                        "<html><body><h1>Access denied</h1></body></html>",
+                        "UTF-8");
                 entity.setContentType("text/html; charset=UTF-8");
                 response.setEntity(entity);
             } else {

Modified: httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/examples/nio/NHttpServer.java Sun Mar  2 04:23:03 2008
@@ -33,8 +33,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InterruptedIOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 import java.net.InetSocketAddress;
 import java.net.URLDecoder;
 
@@ -45,22 +43,21 @@
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.MethodNotSupportedException;
-import org.apache.http.entity.ContentProducer;
-import org.apache.http.entity.EntityTemplate;
-import org.apache.http.entity.FileEntity;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.params.BasicHttpParams;
 import org.apache.http.impl.nio.DefaultServerIOEventDispatch;
 import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
 import org.apache.http.nio.NHttpConnection;
-import org.apache.http.nio.protocol.EventListener;
+import org.apache.http.nio.entity.NFileEntity;
+import org.apache.http.nio.entity.NStringEntity;
 import org.apache.http.nio.protocol.BufferingHttpServiceHandler;
+import org.apache.http.nio.protocol.EventListener;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.ListeningIOReactor;
+import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
 import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.BasicHttpProcessor;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpRequestHandler;
@@ -91,22 +88,22 @@
         httpproc.addInterceptor(new ResponseServer());
         httpproc.addInterceptor(new ResponseContent());
         httpproc.addInterceptor(new ResponseConnControl());
-        
+
         BufferingHttpServiceHandler handler = new BufferingHttpServiceHandler(
                 httpproc,
                 new DefaultHttpResponseFactory(),
                 new DefaultConnectionReuseStrategy(),
                 params);
-        
+
         // Set up request handlers
         HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
         reqistry.register("*", new HttpFileHandler(args[0]));
-        
+
         handler.setHandlerResolver(reqistry);
-        
+
         // Provide an event logger
         handler.setEventListener(new EventLogger());
-        
+
         IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch(handler, params);
         ListeningIOReactor ioReactor = new DefaultListeningIOReactor(2, params);
         try {
@@ -121,22 +118,22 @@
     }
 
     static class HttpFileHandler implements HttpRequestHandler  {
-        
+
         private final String docRoot;
-        
+
         public HttpFileHandler(final String docRoot) {
             super();
             this.docRoot = docRoot;
         }
-        
+
         public void handle(
-                final HttpRequest request, 
+                final HttpRequest request,
                 final HttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
 
             String method = request.getRequestLine().getMethod().toUpperCase();
             if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
-                throw new MethodNotSupportedException(method + " method not supported"); 
+                throw new MethodNotSupportedException(method + " method not supported");
             }
 
             if (request instanceof HttpEntityEnclosingRequest) {
@@ -144,59 +141,41 @@
                 byte[] entityContent = EntityUtils.toByteArray(entity);
                 System.out.println("Incoming entity content (bytes): " + entityContent.length);
             }
-            
+
             String target = request.getRequestLine().getUri();
             final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8"));
             if (!file.exists()) {
 
                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
-                EntityTemplate body = new EntityTemplate(new ContentProducer() {
-                    
-                    public void writeTo(final OutputStream outstream) throws IOException {
-                        OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); 
-                        writer.write("<html><body><h1>");
-                        writer.write("File ");
-                        writer.write(file.getPath());
-                        writer.write(" not found");
-                        writer.write("</h1></body></html>");
-                        writer.flush();
-                    }
-                    
-                });
-                body.setContentType("text/html; charset=UTF-8");
-                response.setEntity(body);
+                NStringEntity entity = new NStringEntity(
+                        "<html><body><h1>File" + file.getPath() +
+                        " not found</h1></body></html>", "UTF-8");
+                entity.setContentType("text/html; charset=UTF-8");
+                response.setEntity(entity);
                 System.out.println("File " + file.getPath() + " not found");
-                
+
             } else if (!file.canRead() || file.isDirectory()) {
-                
+
                 response.setStatusCode(HttpStatus.SC_FORBIDDEN);
-                EntityTemplate body = new EntityTemplate(new ContentProducer() {
-                    
-                    public void writeTo(final OutputStream outstream) throws IOException {
-                        OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8"); 
-                        writer.write("<html><body><h1>");
-                        writer.write("Access denied");
-                        writer.write("</h1></body></html>");
-                        writer.flush();
-                    }
-                    
-                });
-                body.setContentType("text/html; charset=UTF-8");
-                response.setEntity(body);
+                NStringEntity entity = new NStringEntity(
+                        "<html><body><h1>Access denied</h1></body></html>",
+                        "UTF-8");
+                entity.setContentType("text/html; charset=UTF-8");
+                response.setEntity(entity);
                 System.out.println("Cannot read file " + file.getPath());
-                
+
             } else {
-                
+
                 response.setStatusCode(HttpStatus.SC_OK);
-                FileEntity body = new FileEntity(file, "text/html");
+                NFileEntity body = new NFileEntity(file, "text/html");
                 response.setEntity(body);
                 System.out.println("Serving file " + file.getPath());
-                
+
             }
         }
-        
+
     }
-    
+
     static class EventLogger implements EventListener {
 
         public void connectionOpen(final NHttpConnection conn) {
@@ -218,7 +197,7 @@
         public void fatalProtocolException(final HttpException ex, final NHttpConnection conn) {
             System.err.println("HTTP error: " + ex.getMessage());
         }
-        
+
     }
-        
+
 }

Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NFileEntity.java Sun Mar  2 04:23:03 2008
@@ -69,6 +69,10 @@
         setContentType(contentType);
     }
 
+    public NFileEntity(final File file, final String contentType) {
+        this(file, contentType, true);
+    }
+
     public void finish() {
         try {
             if(fileChannel != null)

Added: 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=632746&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java (added)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java Sun Mar  2 04:23:03 2008
@@ -0,0 +1,94 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * 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.entity;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.entity.HttpEntityWrapper;
+import org.apache.http.nio.ContentEncoder;
+import org.apache.http.nio.IOControl;
+
+public class NHttpEntityWrapper
+    extends HttpEntityWrapper implements ProducingNHttpEntity {
+
+    private final ReadableByteChannel channel;
+    private final ByteBuffer buffer;
+
+    public NHttpEntityWrapper(final HttpEntity httpEntity) throws IOException {
+        super(httpEntity);
+        this.channel = Channels.newChannel(httpEntity.getContent());
+        this.buffer = ByteBuffer.allocate(4096);
+    }
+
+    public InputStream getContent() throws IOException, IllegalStateException {
+        throw new UnsupportedOperationException("Does not support blocking methods");
+    }
+
+    public boolean isStreaming() {
+        return true;
+    }
+
+    public void writeTo(OutputStream out) throws IOException {
+        throw new UnsupportedOperationException("Does not support blocking methods");
+    }
+
+    public void consumeContent() throws IOException, UnsupportedOperationException {
+        throw new UnsupportedOperationException("Does not support blocking methods");
+    }
+
+    public void produceContent(
+            final ContentEncoder encoder,
+            final IOControl ioctrl) throws IOException {
+        int i = this.channel.read(this.buffer);
+        this.buffer.flip();
+        encoder.write(this.buffer);
+        this.buffer.compact();
+        if (i == -1) {
+            encoder.complete();
+            this.channel.close();
+        }
+    }
+
+    public void finish() {
+        try {
+            this.channel.close();
+        } catch (IOException ignore) {
+        }
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/entity/NHttpEntityWrapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/AsyncNHttpServiceHandler.java Sun Mar  2 04:23:03 2008
@@ -54,6 +54,7 @@
 import org.apache.http.nio.entity.ConsumingNHttpEntity;
 import org.apache.http.nio.entity.ConsumingNHttpEntityTemplate;
 import org.apache.http.nio.entity.NByteArrayEntity;
+import org.apache.http.nio.entity.NHttpEntityWrapper;
 import org.apache.http.nio.entity.ProducingNHttpEntity;
 import org.apache.http.nio.entity.SkipContentListener;
 import org.apache.http.nio.util.ByteBufferAllocator;
@@ -346,7 +347,7 @@
         HttpResponse response = conn.getHttpResponse();
 
         try {
-            ProducingNHttpEntity entity = (ProducingNHttpEntity) response.getEntity();
+            ProducingNHttpEntity entity = connState.getProducingEntity();
             entity.produceContent(encoder, conn);
 
             if (encoder.isCompleted()) {
@@ -450,8 +451,11 @@
 
         HttpEntity entity = response.getEntity();
         if (entity != null) {
-            ProducingNHttpEntity producingEntity = (ProducingNHttpEntity) entity;
-            connState.setProducingEntity(producingEntity);
+            if (entity instanceof ProducingNHttpEntity) {
+                connState.setProducingEntity((ProducingNHttpEntity) entity);
+            } else {
+                connState.setProducingEntity(new NHttpEntityWrapper(entity));
+            }
         }
 
         conn.submitResponse(response);

Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java Sun Mar  2 04:23:03 2008
@@ -32,451 +32,155 @@
 package org.apache.http.nio.protocol;
 
 import java.io.IOException;
-import java.io.OutputStream;
 
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.MethodNotSupportedException;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.ProtocolException;
-import org.apache.http.UnsupportedHttpVersionException;
-import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.nio.ContentDecoder;
 import org.apache.http.nio.ContentEncoder;
 import org.apache.http.nio.NHttpServerConnection;
 import org.apache.http.nio.NHttpServiceHandler;
-import org.apache.http.nio.entity.ContentBufferEntity;
-import org.apache.http.nio.entity.ContentOutputStream;
+import org.apache.http.nio.entity.BufferingNHttpEntity;
+import org.apache.http.nio.entity.ConsumingNHttpEntity;
 import org.apache.http.nio.util.ByteBufferAllocator;
-import org.apache.http.nio.util.ContentInputBuffer;
-import org.apache.http.nio.util.ContentOutputBuffer;
 import org.apache.http.nio.util.HeapByteBufferAllocator;
-import org.apache.http.nio.util.SimpleInputBuffer;
-import org.apache.http.nio.util.SimpleOutputBuffer;
 import org.apache.http.params.HttpParams;
-import org.apache.http.params.DefaultedHttpParams;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpExpectationVerifier;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.util.EncodingUtils;
+import org.apache.http.protocol.HttpRequestHandlerResolver;
 
 /**
- * HTTP service handler implementation that buffers the content of HTTP messages 
+ * HTTP service handler implementation that buffers the content of HTTP messages
  * entirely in memory and processes HTTP requests on the main I/O thread.
- * 
- * <p>This service handler should be used only when dealing with HTTP messages 
+ *
+ * <p>This service handler should be used only when dealing with HTTP messages
  * that are known to be limited in length</p>
- * 
+ *
  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
  *
  */
-public class BufferingHttpServiceHandler extends NHttpServiceHandlerBase 
-                                         implements NHttpServiceHandler {
+public class BufferingHttpServiceHandler implements NHttpServiceHandler {
+
+    private final AsyncNHttpServiceHandler asyncHandler;
+
+    private HttpRequestHandlerResolver handlerResolver;
 
     public BufferingHttpServiceHandler(
-            final HttpProcessor httpProcessor, 
+            final HttpProcessor httpProcessor,
             final HttpResponseFactory responseFactory,
             final ConnectionReuseStrategy connStrategy,
             final ByteBufferAllocator allocator,
             final HttpParams params) {
-        super(httpProcessor, responseFactory, connStrategy, allocator, params);
+        super();
+        this.asyncHandler = new AsyncNHttpServiceHandler(
+                httpProcessor,
+                responseFactory,
+                connStrategy,
+                allocator,
+                params);
+        this.asyncHandler.setHandlerResolver(new RequestHandlerResolverAdaptor());
     }
 
     public BufferingHttpServiceHandler(
-            final HttpProcessor httpProcessor, 
+            final HttpProcessor httpProcessor,
             final HttpResponseFactory responseFactory,
             final ConnectionReuseStrategy connStrategy,
             final HttpParams params) {
-        this(httpProcessor, responseFactory, connStrategy, 
+        this(httpProcessor, responseFactory, connStrategy,
                 new HeapByteBufferAllocator(), params);
     }
-    
-    public void connected(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
 
-        ServerConnState connState = new ServerConnState(allocator); 
-        context.setAttribute(CONN_STATE, connState);
+    public void setEventListener(final EventListener eventListener) {
+        this.asyncHandler.setEventListener(eventListener);
+    }
 
-        if (this.eventListener != null) {
-            this.eventListener.connectionOpen(conn);
-        }
+    public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
+        this.asyncHandler.setExpectationVerifier(expectationVerifier);
     }
 
-    public void requestReceived(final NHttpServerConnection conn) {
-        HttpContext context = conn.getContext();
-        
-        HttpRequest request = conn.getHttpRequest();
-        request.setParams(new DefaultedHttpParams(request.getParams(), this.params));
-
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
-
-        // Update connection state
-        connState.resetInput();
-        connState.setRequest(request);
-        connState.setInputState(ServerConnState.REQUEST_RECEIVED);
-        
-        ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
-            // Downgrade protocol version if greater than HTTP/1.1 
-            ver = HttpVersion.HTTP_1_1;
-        }
+    public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) {
+        this.handlerResolver = handlerResolver;
+    }
 
-        HttpResponse response;
-        
-        try {
-
-            if (request instanceof HttpEntityEnclosingRequest) {
-                if (((HttpEntityEnclosingRequest) request).expectContinue()) {
-                    response = this.responseFactory.newHttpResponse(
-                            ver, HttpStatus.SC_CONTINUE, context);
-                    response.setParams(
-                            new DefaultedHttpParams(response.getParams(), this.params));
-                    
-                    if (this.expectationVerifier != null) {
-                        try {
-                            this.expectationVerifier.verify(request, response, context);
-                        } catch (HttpException ex) {
-                            response = this.responseFactory.newHttpResponse(
-                                    HttpVersion.HTTP_1_0, 
-                                    HttpStatus.SC_INTERNAL_SERVER_ERROR, 
-                                    context);
-                            response.setParams(
-                                    new DefaultedHttpParams(response.getParams(), this.params));
-                            handleException(ex, response);
-                        }
-                    }
-                    
-                    if (response.getStatusLine().getStatusCode() < 200) {
-                        // Send 1xx response indicating the server expections
-                        // have been met
-                        conn.submitResponse(response);
-                    } else {
-                        // The request does not meet the server expections
-                        conn.resetInput();
-                        connState.resetInput();
-                        sendResponse(conn, response);
-                    }
-                }
-                // Request content is expected. 
-                // Wait until the request content is fully received
-            } else {
-                // No request content is expected. 
-                // Process request right away
-                conn.suspendInput();
-                processRequest(conn, request);
-            }
-            
-        } catch (IOException ex) {
-            shutdownConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalIOException(ex, conn);
-            }
-        } catch (HttpException ex) {
-            closeConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalProtocolException(ex, conn);
-            }
-        }
-        
+    public void connected(final NHttpServerConnection conn) {
+        this.asyncHandler.connected(conn);
     }
 
-    public void closed(final NHttpServerConnection conn) {
-        if (this.eventListener != null) {
-            this.eventListener.connectionClosed(conn);
-        }
+    public void requestReceived(final NHttpServerConnection conn) {
+        this.asyncHandler.requestReceived(conn);
     }
 
-    public void exception(final NHttpServerConnection conn, final HttpException httpex) {
-        if (conn.isResponseSubmitted()) {
-            if (eventListener != null) {
-                eventListener.fatalProtocolException(httpex, conn);
-            }
-            return;
-        }
-        
-        HttpContext context = conn.getContext();
-        try {
-            HttpResponse response = this.responseFactory.newHttpResponse(
-                    HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
-            response.setParams(
-                    new DefaultedHttpParams(response.getParams(), this.params));
-            handleException(httpex, response);
-            response.setEntity(null);
-            sendResponse(conn, response);
-            
-        } catch (IOException ex) {
-            shutdownConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalIOException(ex, conn);
-            }
-        } catch (HttpException ex) {
-            closeConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalProtocolException(ex, conn);
-            }
-        }
+    public void closed(final NHttpServerConnection conn) {
+        this.asyncHandler.closed(conn);
     }
 
     public void inputReady(final NHttpServerConnection conn, final ContentDecoder decoder) {
-        HttpContext context = conn.getContext();
-        HttpRequest request = conn.getHttpRequest();
-
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
-        ContentInputBuffer buffer = connState.getInbuffer();
-
-        // Update connection state
-        connState.setInputState(ServerConnState.REQUEST_BODY_STREAM);
-        
-        try {
-            buffer.consumeContent(decoder);
-            if (decoder.isCompleted()) {
-                // Request entity has been fully received
-                connState.setInputState(ServerConnState.REQUEST_BODY_DONE);
-
-                // Create a wrapper entity instead of the original one
-                HttpEntityEnclosingRequest entityReq = (HttpEntityEnclosingRequest) request;
-                if (entityReq.getEntity() != null) {
-                    entityReq.setEntity(new ContentBufferEntity(
-                            entityReq.getEntity(), 
-                            connState.getInbuffer()));
-                }
-                conn.suspendInput();
-                processRequest(conn, request);
-            }
-            
-        } catch (IOException ex) {
-            shutdownConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalIOException(ex, conn);
-            }
-        } catch (HttpException ex) {
-            closeConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalProtocolException(ex, conn);
-            }
-        }
+        this.asyncHandler.inputReady(conn, decoder);
     }
 
     public void responseReady(final NHttpServerConnection conn) {
+        this.asyncHandler.responseReady(conn);
     }
 
     public void outputReady(final NHttpServerConnection conn, final ContentEncoder encoder) {
+        this.asyncHandler.outputReady(conn, encoder);
+    }
 
-        HttpContext context = conn.getContext();
-        HttpResponse response = conn.getHttpResponse();
+    public void exception(final NHttpServerConnection conn, final HttpException httpex) {
+        this.asyncHandler.exception(conn, httpex);
+    }
 
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
-        ContentOutputBuffer buffer = connState.getOutbuffer();
+    public void exception(final NHttpServerConnection conn, final IOException ioex) {
+        this.asyncHandler.exception(conn, ioex);
+    }
 
-        // Update connection state
-        connState.setOutputState(ServerConnState.RESPONSE_BODY_STREAM);
-        
-        try {
-            
-            buffer.produceContent(encoder);
-            if (encoder.isCompleted()) {
-                connState.setOutputState(ServerConnState.RESPONSE_BODY_DONE);
-                connState.resetOutput();
-                if (!this.connStrategy.keepAlive(response, context)) {
-                    conn.close();
-                } else {
-                    conn.requestInput();
-                }
-            }
-            
-        } catch (IOException ex) {
-            shutdownConnection(conn, ex);
-            if (this.eventListener != null) {
-                this.eventListener.fatalIOException(ex, conn);
-            }
-        }
+    public void timeout(NHttpServerConnection conn) {
+        this.asyncHandler.timeout(conn);
     }
 
-    private void handleException(final HttpException ex, final HttpResponse response) {
-        int code = HttpStatus.SC_INTERNAL_SERVER_ERROR;
-        if (ex instanceof MethodNotSupportedException) {
-            code = HttpStatus.SC_NOT_IMPLEMENTED;
-        } else if (ex instanceof UnsupportedHttpVersionException) {
-            code = HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED;
-        } else if (ex instanceof ProtocolException) {
-            code = HttpStatus.SC_BAD_REQUEST;
-        }
-        response.setStatusCode(code);
-        
-        byte[] msg = EncodingUtils.getAsciiBytes(ex.getMessage());
-        ByteArrayEntity entity = new ByteArrayEntity(msg);
-        entity.setContentType("text/plain; charset=US-ASCII");
-        response.setEntity(entity);
-    }
-    
-    private void processRequest(
-            final NHttpServerConnection conn,
-            final HttpRequest request) throws IOException, HttpException {
-        
-        HttpContext context = conn.getContext();
-        ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
-
-        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
-            // Downgrade protocol version if greater than HTTP/1.1 
-            ver = HttpVersion.HTTP_1_1;
-        }
+    class RequestHandlerResolverAdaptor implements NHttpRequestHandlerResolver {
 
-        HttpResponse response = this.responseFactory.newHttpResponse(
-                ver, 
-                HttpStatus.SC_OK, 
-                conn.getContext());
-        response.setParams(
-                new DefaultedHttpParams(response.getParams(), this.params));
-        
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, request);
-        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
-        context.setAttribute(ExecutionContext.HTTP_RESPONSE, response);
-        
-        try {
-
-            this.httpProcessor.process(request, context);
-
-            HttpRequestHandler handler = null;
-            if (this.handlerResolver != null) {
-                String requestURI = request.getRequestLine().getUri();
-                handler = this.handlerResolver.lookup(requestURI);
-            }
+        public NHttpRequestHandler lookup(final String requestURI) {
+            HttpRequestHandler handler = handlerResolver.lookup(requestURI);
             if (handler != null) {
-                handler.handle(request, response, context);
+                return new RequestHandlerAdaptor(handler);
             } else {
-                response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
+                return null;
             }
-            
-        } catch (HttpException ex) {
-            response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, 
-                    HttpStatus.SC_INTERNAL_SERVER_ERROR, context);
-            response.setParams(
-                    new DefaultedHttpParams(response.getParams(), this.params));
-            handleException(ex, response);
         }
 
-        sendResponse(conn, response);
     }
 
-    private void sendResponse(
-            final NHttpServerConnection conn,
-            final HttpResponse response) throws IOException, HttpException {
-
-        HttpContext context = conn.getContext();
-
-        ServerConnState connState = (ServerConnState) context.getAttribute(CONN_STATE);
-        ContentOutputBuffer buffer = connState.getOutbuffer();
+    static class RequestHandlerAdaptor extends SimpleNHttpRequestHandler {
 
-        this.httpProcessor.process(response, context);
+        private final HttpRequestHandler requestHandler;
 
-        if (!canResponseHaveBody(connState.getRequest(), response)) {
-            response.setEntity(null);
-        }
-        
-        conn.submitResponse(response);
-
-        // Update connection state
-        connState.setOutputState(ServerConnState.RESPONSE_SENT);
-
-        HttpEntity entity = response.getEntity();
-        if (entity != null) {
-            OutputStream outstream = new ContentOutputStream(buffer);
-            entity.writeTo(outstream);
-            outstream.flush();
-            outstream.close();
-        } else {
-            connState.resetOutput();
-            if (!this.connStrategy.keepAlive(response, context)) {
-                conn.close();
-            } else {
-                conn.requestInput();
-            }
-        }
-    }
-
-    static class ServerConnState {
-        
-        public static final int READY                      = 0;
-        public static final int REQUEST_RECEIVED           = 1;
-        public static final int REQUEST_BODY_STREAM        = 2;
-        public static final int REQUEST_BODY_DONE          = 4;
-        public static final int RESPONSE_SENT              = 8;
-        public static final int RESPONSE_BODY_STREAM       = 16;
-        public static final int RESPONSE_BODY_DONE         = 32;
-        
-        private SimpleInputBuffer inbuffer; 
-        private ContentOutputBuffer outbuffer;
-
-        private int inputState;
-        private int outputState;
-        
-        private HttpRequest request;
-        private final ByteBufferAllocator allocator;
-        
-        public ServerConnState(final ByteBufferAllocator allocator) {
+        public RequestHandlerAdaptor(final HttpRequestHandler requestHandler) {
             super();
-            this.inputState = READY;
-            this.outputState = READY;
-            this.allocator = allocator;
+            this.requestHandler = requestHandler;
         }
 
-        public ContentInputBuffer getInbuffer() {
-            if (this.inbuffer == null) {
-                this.inbuffer = new SimpleInputBuffer(2048, allocator);
-            }
-            return this.inbuffer;
+        public ConsumingNHttpEntity entityRequest(
+                final HttpEntityEnclosingRequest request,
+                final HttpContext context) throws HttpException, IOException {
+            return new BufferingNHttpEntity(
+                    request.getEntity(),
+                    new HeapByteBufferAllocator());
+        }
+
+        @Override
+        public void handle(
+                final HttpRequest request,
+                final HttpResponse response,
+                final HttpContext context) throws HttpException, IOException {
+            this.requestHandler.handle(request, response, context);
         }
 
-        public ContentOutputBuffer getOutbuffer() {
-            if (this.outbuffer == null) {
-                this.outbuffer = new SimpleOutputBuffer(2048, allocator);
-            }
-            return this.outbuffer;
-        }
-        
-        public int getInputState() {
-            return this.inputState;
-        }
-
-        public void setInputState(int inputState) {
-            this.inputState = inputState;
-        }
-
-        public int getOutputState() {
-            return this.outputState;
-        }
-
-        public void setOutputState(int outputState) {
-            this.outputState = outputState;
-        }
-
-        public HttpRequest getRequest() {
-            return this.request;
-        }
-
-        public void setRequest(final HttpRequest request) {
-            this.request = request;
-        }
-
-        public void resetInput() {
-            this.inbuffer = null;
-            this.request = null;
-            this.inputState = READY;
-        }
-        
-        public void resetOutput() {
-            this.outbuffer = null;
-            this.outputState = READY;
-        }
-        
     }
-    
+
 }

Modified: httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/NHttpClientHandlerBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/NHttpClientHandlerBase.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/NHttpClientHandlerBase.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/NHttpClientHandlerBase.java Sun Mar  2 04:23:03 2008
@@ -31,11 +31,7 @@
 
 package org.apache.http.nio.protocol;
 
-import java.io.IOException;
-
 import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpException;
-import org.apache.http.nio.NHttpClientConnection;
 import org.apache.http.nio.util.ByteBufferAllocator;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpProcessor;
@@ -55,26 +51,6 @@
             throw new IllegalArgumentException("HTTP request execution handler may not be null.");
         }
         this.execHandler = execHandler;
-    }
-
-    public void closed(final NHttpClientConnection conn) {
-        if (this.eventListener != null) {
-            this.eventListener.connectionClosed(conn);
-        }
-    }
-
-    public void exception(final NHttpClientConnection conn, final HttpException ex) {
-        closeConnection(conn, ex);
-        if (this.eventListener != null) {
-            this.eventListener.fatalProtocolException(ex, conn);
-        }
-    }
-
-    public void exception(final NHttpClientConnection conn, final IOException ex) {
-        shutdownConnection(conn, ex);
-        if (this.eventListener != null) {
-            this.eventListener.fatalIOException(ex, conn);
-        }
     }
 
 }

Modified: httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestBufferingNHttpHandlers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestBufferingNHttpHandlers.java?rev=632746&r1=632745&r2=632746&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestBufferingNHttpHandlers.java (original)
+++ httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/protocol/TestBufferingNHttpHandlers.java Sun Mar  2 04:23:03 2008
@@ -49,8 +49,6 @@
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.message.BasicHttpEntityEnclosingRequest;
@@ -65,6 +63,8 @@
 import org.apache.http.nio.NHttpClientHandler;
 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.NStringEntity;
 import org.apache.http.nio.reactor.ListenerEndpoint;
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.CoreConnectionPNames;
@@ -91,7 +91,7 @@
  * HttpCore NIO integration tests.
  *
  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
- * 
+ *
  * @version $Id$
  */
 public class TestBufferingNHttpHandlers extends TestCase {
@@ -115,7 +115,7 @@
 
     private TestHttpServer server;
     private TestHttpClient client;
-    
+
     @Override
     protected void setUp() throws Exception {
         HttpParams serverParams = new BasicHttpParams();
@@ -125,9 +125,9 @@
             .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
             .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
             .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "TEST-SERVER/1.1");
-        
+
         this.server = new TestHttpServer(serverParams);
-        
+
         HttpParams clientParams = new BasicHttpParams();
         clientParams
             .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
@@ -136,7 +136,7 @@
             .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
             .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
             .setParameter(CoreProtocolPNames.USER_AGENT, "TEST-CLIENT/1.1");
-        
+
         this.client = new TestHttpClient(clientParams);
     }
 
@@ -145,7 +145,7 @@
         this.server.shutdown();
         this.client.shutdown();
     }
-    
+
     private NHttpServiceHandler createHttpServiceHandler(
             final HttpRequestHandler requestHandler,
             final HttpExpectationVerifier expectationVerifier) {
@@ -165,10 +165,10 @@
                 new SimpleHttpRequestHandlerResolver(requestHandler));
         serviceHandler.setExpectationVerifier(expectationVerifier);
         serviceHandler.setEventListener(new SimpleEventListener());
-        
+
         return serviceHandler;
     }
-    
+
     private NHttpClientHandler createHttpClientHandler(
             final HttpRequestExecutionHandler requestExecutionHandler) {
         BasicHttpProcessor httpproc = new BasicHttpProcessor();
@@ -187,31 +187,31 @@
         clientHandler.setEventListener(new SimpleEventListener());
         return clientHandler;
     }
-    
+
     /**
-     * This test case executes a series of simple (non-pipelined) GET requests 
-     * over multiple connections. 
+     * This test case executes a series of simple (non-pipelined) GET requests
+     * over multiple connections.
      */
     public void testSimpleHttpGets() throws Exception {
-        
+
         final int connNo = 3;
         final int reqNo = 20;
-        final RequestCount requestCount = new RequestCount(connNo * reqNo); 
+        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 HttpRequest request,
+                    final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
-                
+
                 String s = request.getRequestLine().getUri();
                 URI uri;
                 try {
@@ -221,12 +221,12 @@
                 }
                 int index = Integer.parseInt(uri.getQuery());
                 byte[] bytes = requestData.getBytes(index);
-                ByteArrayEntity entity = new ByteArrayEntity(bytes); 
+                NByteArrayEntity entity = new NByteArrayEntity(bytes);
                 response.setEntity(entity);
             }
-            
+
         };
-        
+
         HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
 
             public void initalizeContext(final HttpContext context, final Object attachment) {
@@ -247,11 +247,11 @@
                 }
                 return get;
             }
-            
+
             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++;
@@ -271,11 +271,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
 
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 null);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -283,20 +283,20 @@
 
         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()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData.get(i));
         }
-     
+
         requestCount.await(10000);
         assertEquals(0, requestCount.getValue());
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -307,55 +307,55 @@
             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]);
                 }
             }
         }
-        
+
     }
 
     /**
-     * This test case executes a series of simple (non-pipelined) POST requests 
-     * with content length delimited content over multiple connections. 
+     * This test case executes a series of simple (non-pipelined) POST requests
+     * with content length delimited content over multiple connections.
      */
     public void testSimpleHttpPostsWithContentLength() throws Exception {
-        
+
         final int connNo = 3;
         final int reqNo = 20;
-        final RequestCount requestCount = new RequestCount(connNo * reqNo); 
+        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 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);
+
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     outgoing.setChunked(false);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content"); 
+                    NStringEntity outgoing = new NStringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
-            
+
         };
-        
+
         HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
 
             public void initalizeContext(final HttpContext context, final Object attachment) {
@@ -374,18 +374,18 @@
                     post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
 
                     byte[] data = requestData.getBytes(i);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     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++;
@@ -405,11 +405,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
-        
+
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 null);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -417,20 +417,20 @@
 
         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()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData.get(i));
         }
-     
+
         requestCount.await(10000);
         assertEquals(0, requestCount.getValue());
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -441,54 +441,54 @@
             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]);
                 }
             }
         }
-        
+
     }
 
     /**
-     * This test case executes a series of simple (non-pipelined) POST requests 
-     * with chunk coded content content over multiple connections. 
+     * This test case executes a series of simple (non-pipelined) POST requests
+     * with chunk coded content content over multiple connections.
      */
     public void testSimpleHttpPostsChunked() throws Exception {
-        
+
         final int connNo = 3;
         final int reqNo = 20;
-        final RequestCount requestCount = new RequestCount(connNo * reqNo); 
+        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 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);
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     outgoing.setChunked(true);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content"); 
+                    NStringEntity outgoing = new NStringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
-            
+
         };
-        
+
         HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
 
             public void initalizeContext(final HttpContext context, final Object attachment) {
@@ -506,24 +506,24 @@
                 if (i < reqNo) {
                     post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
                     byte[] data = requestData.getBytes(i);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     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);
@@ -538,11 +538,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
-        
+
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 null);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -550,23 +550,23 @@
 
         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()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData.get(i));
         }
-     
+
         requestCount.await(10000);
         if (requestCount.isAborted()) {
             System.out.println("Test case aborted");
         }
         assertEquals(0, requestCount.getValue());
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -577,60 +577,60 @@
             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]);
                 }
             }
         }
-        
+
     }
 
     /**
-     * This test case executes a series of simple (non-pipelined) HTTP/1.0 
-     * POST requests over multiple persistent connections. 
+     * This test case executes a series of simple (non-pipelined) HTTP/1.0
+     * POST requests over multiple persistent connections.
      */
     public void testSimpleHttpPostsHTTP10() throws Exception {
-        
+
         final int connNo = 3;
         final int reqNo = 20;
-        final RequestCount requestCount = new RequestCount(connNo * reqNo); 
+        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 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);
+
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     outgoing.setChunked(false);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content"); 
+                    NStringEntity outgoing = new NStringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
-            
+
         };
-        
+
         // Set protocol level to HTTP/1.0
         this.client.getParams().setParameter(
                 CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
-        
+
         HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
 
             public void initalizeContext(final HttpContext context, final Object attachment) {
@@ -648,14 +648,14 @@
                 if (i < reqNo) {
                     post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
                     byte[] data = requestData.getBytes(i);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     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);
@@ -679,11 +679,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
-        
+
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 null);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -691,20 +691,20 @@
 
         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()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData.get(i));
         }
-     
+
         requestCount.await(10000);
         assertEquals(0, requestCount.getValue());
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -715,57 +715,57 @@
             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]);
                 }
             }
         }
-        
+
     }
 
     /**
-     * This test case executes a series of simple (non-pipelined) POST requests 
-     * over multiple connections using the 'expect: continue' handshake. 
+     * This test case executes a series of simple (non-pipelined) POST requests
+     * over multiple connections using the 'expect: continue' handshake.
      */
     public void testHttpPostsWithExpectContinue() throws Exception {
-        
+
         final int connNo = 3;
         final int reqNo = 20;
-        final RequestCount requestCount = new RequestCount(connNo * reqNo); 
+        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 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);
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     outgoing.setChunked(true);
                     response.setEntity(outgoing);
                 } else {
-                    StringEntity outgoing = new StringEntity("No content"); 
+                    NStringEntity outgoing = new NStringEntity("No content");
                     response.setEntity(outgoing);
                 }
             }
-            
+
         };
 
         // Activate 'expect: continue' handshake
         this.client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
-        
+
         HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
 
             public void initalizeContext(final HttpContext context, final Object attachment) {
@@ -783,24 +783,24 @@
                 if (i < reqNo) {
                     post = new BasicHttpEntityEnclosingRequest("POST", "/?" + i);
                     byte[] data = requestData.getBytes(i);
-                    ByteArrayEntity outgoing = new ByteArrayEntity(data);
+                    NByteArrayEntity outgoing = new NByteArrayEntity(data);
                     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);
@@ -815,11 +815,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
-        
+
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 null);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -827,20 +827,20 @@
 
         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()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData.get(i));
         }
-     
+
         requestCount.await(10000);
         assertEquals(0, requestCount.getValue());
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -851,44 +851,44 @@
             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]);
                 }
             }
         }
-        
+
     }
 
     /**
-     * This test case executes a series of simple (non-pipelined) POST requests 
-     * over multiple connections that do not meet the target server expectations. 
+     * This test case executes a series of simple (non-pipelined) POST requests
+     * over multiple connections that do not meet the target server expectations.
      */
     public void testHttpPostsWithExpectationVerification() throws Exception {
-        
+
         final int reqNo = 3;
-        final RequestCount requestCount = new RequestCount(reqNo); 
+        final RequestCount requestCount = new RequestCount(reqNo);
         final ResponseSequence responses = new ResponseSequence();
-        
+
         HttpRequestHandler requestHandler = new HttpRequestHandler() {
 
             public void handle(
-                    final HttpRequest request, 
-                    final HttpResponse response, 
+                    final HttpRequest request,
+                    final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
-                
-                StringEntity outgoing = new StringEntity("No content"); 
+
+                NStringEntity outgoing = new NStringEntity("No content");
                 response.setEntity(outgoing);
             }
-            
+
         };
-        
+
         HttpExpectationVerifier expectationVerifier = new HttpExpectationVerifier() {
 
             public void verify(
-                    final HttpRequest request, 
-                    final HttpResponse response, 
+                    final HttpRequest request,
+                    final HttpResponse response,
                     final HttpContext context) throws HttpException {
                 Header someheader = request.getFirstHeader("Secret");
                 if (someheader != null) {
@@ -901,13 +901,13 @@
                     }
                     if (secretNumber < 2) {
                         response.setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
-                        ByteArrayEntity outgoing = new ByteArrayEntity(
-                                EncodingUtils.getAsciiBytes("Wrong secret number")); 
+                        NByteArrayEntity outgoing = new NByteArrayEntity(
+                                EncodingUtils.getAsciiBytes("Wrong secret number"));
                         response.setEntity(outgoing);
                     }
                 }
             }
-            
+
         };
 
         // Activate 'expect: continue' handshake
@@ -930,24 +930,24 @@
                 if (i < reqNo) {
                     post = new BasicHttpEntityEnclosingRequest("POST", "/");
                     post.addHeader("Secret", Integer.toString(i));
-                    ByteArrayEntity outgoing = new ByteArrayEntity(
-                            EncodingUtils.getAsciiBytes("No content")); 
+                    NByteArrayEntity outgoing = new NByteArrayEntity(
+                            EncodingUtils.getAsciiBytes("No content"));
                     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);
-                
+
                 ResponseSequence list = (ResponseSequence) context.getAttribute("LIST");
                 int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
                 i++;
                 context.setAttribute("RES-COUNT", new Integer(i));
-                
+
                 HttpEntity entity = response.getEntity();
                 if (entity != null) {
                     try {
@@ -957,7 +957,7 @@
                         return;
                     }
                 }
-                
+
                 list.addResponse(response);
                 requestCount.decrement();
 
@@ -965,11 +965,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
-        
+
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 expectationVerifier);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -977,17 +977,17 @@
 
         this.server.start(serviceHandler);
         this.client.start(clientHandler);
-        
+
         ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
         InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
-        
+
         this.client.openConnection(
-                new InetSocketAddress("localhost", serverAddress.getPort()), 
+                new InetSocketAddress("localhost", serverAddress.getPort()),
                 responses);
-     
+
         requestCount.await(1000);
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -999,20 +999,20 @@
         response = responses.getResponse(2);
         assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
     }
-    
+
     /**
-     * This test case executes a series of simple (non-pipelined) HEAD requests 
-     * over multiple connections. 
+     * This test case executes a series of simple (non-pipelined) HEAD requests
+     * over multiple connections.
      */
     public void testSimpleHttpHeads() throws Exception {
-        
+
         final int connNo = 3;
         final int reqNo = 20;
-        final RequestCount requestCount = new RequestCount(connNo * reqNo * 2); 
-        
+        final RequestCount requestCount = new RequestCount(connNo * reqNo * 2);
+
         final ByteSequence requestData = new ByteSequence();
         requestData.rnd(reqNo);
-        
+
         List<ResponseSequence> responseData1 = new ArrayList<ResponseSequence>(connNo);
         for (int i = 0; i < connNo; i++) {
             responseData1.add(new ResponseSequence());
@@ -1021,16 +1021,16 @@
         for (int i = 0; i < connNo; i++) {
             responseData2.add(new ResponseSequence());
         }
-        
+
         final String[] method = new String[1];
-        
+
         HttpRequestHandler requestHandler = new HttpRequestHandler() {
 
             public void handle(
-                    final HttpRequest request, 
-                    final HttpResponse response, 
+                    final HttpRequest request,
+                    final HttpResponse response,
                     final HttpContext context) throws HttpException, IOException {
-                
+
                 String s = request.getRequestLine().getUri();
                 URI uri;
                 try {
@@ -1041,12 +1041,12 @@
                 int index = Integer.parseInt(uri.getQuery());
 
                 byte[] data = requestData.getBytes(index);
-                ByteArrayEntity entity = new ByteArrayEntity(data); 
+                NByteArrayEntity entity = new NByteArrayEntity(data);
                 response.setEntity(entity);
             }
-            
+
         };
-        
+
         HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
 
             public void initalizeContext(final HttpContext context, final Object attachment) {
@@ -1067,11 +1067,11 @@
                 }
                 return request;
             }
-            
+
             public void handleResponse(final HttpResponse response, final HttpContext context) {
                 NHttpConnection conn = (NHttpConnection) context.getAttribute(
                         ExecutionContext.HTTP_CONNECTION);
-                
+
                 ResponseSequence list = (ResponseSequence) context.getAttribute("LIST");
                 int i = ((Integer) context.getAttribute("RES-COUNT")).intValue();
                 i++;
@@ -1084,11 +1084,11 @@
                     conn.requestInput();
                 }
             }
-            
+
         };
-        
+
         NHttpServiceHandler serviceHandler = createHttpServiceHandler(
-                requestHandler, 
+                requestHandler,
                 null);
 
         NHttpClientHandler clientHandler = createHttpClientHandler(
@@ -1096,19 +1096,19 @@
 
         this.server.start(serviceHandler);
         this.client.start(clientHandler);
-        
+
         ListenerEndpoint endpoint = this.server.getListenerEndpoint();
         endpoint.waitFor();
         InetSocketAddress serverAddress = (InetSocketAddress) endpoint.getAddress();
 
         method[0] = "GET";
-        
+
         for (int i = 0; i < responseData1.size(); i++) {
             this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData1.get(i));
         }
-     
+
         requestCount.await(connNo * reqNo, 10000);
         assertEquals(connNo * reqNo, requestCount.getValue());
 
@@ -1116,14 +1116,14 @@
 
         for (int i = 0; i < responseData2.size(); i++) {
             this.client.openConnection(
-                    new InetSocketAddress("localhost", serverAddress.getPort()), 
+                    new InetSocketAddress("localhost", serverAddress.getPort()),
                     responseData2.get(i));
         }
-     
-     
+
+
         requestCount.await(10000);
         assertEquals(0, requestCount.getValue());
-        
+
         this.client.shutdown();
         this.server.shutdown();
 
@@ -1137,7 +1137,7 @@
                 HttpResponse getResponse = getResponses.getResponse(p);
                 HttpResponse headResponse = headResponses.getResponse(p);
                 assertEquals(null, headResponse.getEntity());
-                
+
                 Header[] getHeaders = getResponse.getAllHeaders();
                 Header[] headHeaders = headResponse.getAllHeaders();
                 assertEquals(getHeaders.length, headHeaders.length);
@@ -1150,5 +1150,5 @@
             }
         }
     }
-    
+
 }