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 2006/11/12 17:05:04 UTC

svn commit: r473977 - in /jakarta/httpcomponents/httpcore/trunk/module-nio/src: examples/org/apache/http/nio/examples/ main/java/org/apache/http/nio/ main/java/org/apache/http/nio/handler/ main/java/org/apache/http/nio/impl/ main/java/org/apache/http/n...

Author: olegk
Date: Sun Nov 12 08:05:03 2006
New Revision: 473977

URL: http://svn.apache.org/viewvc?view=rev&rev=473977
Log:
* The first take at implementing a classic I/O compatibility layer on top of the event-driven HTTP transprot
* Lots of API changes
* Some minor code refactoring

Added:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/AsyncHttpService.java   (with props)
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/ContentIOControl.java
      - copied, changed from r467445, jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputBuffer.java   (with props)
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputStream.java   (with props)
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputBuffer.java   (with props)
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputStream.java   (with props)
Removed:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpClient.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/IOConsumer.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/IOProducer.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/AbstractSessionDataReceiver.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/AbstractSessionDataTransmitter.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/AsyncHttpClientConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/AsyncHttpDataReceiver.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/AsyncHttpDataTransmitter.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/AsyncHttpServerConnection.java
Modified:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServer.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionInputBuffer.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionOutputBuffer.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/handler/NHttpConnectionBase.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/impl/TestSessionInOutBuffers.java

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServer.java?view=diff&rev=473977&r1=473976&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServer.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/AsyncHttpServer.java Sun Nov 12 08:05:03 2006
@@ -10,11 +10,9 @@
 import java.net.URLDecoder;
 
 import org.apache.http.ConnectionClosedException;
-import org.apache.http.HttpConnection;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpServerConnection;
 import org.apache.http.HttpStatus;
 import org.apache.http.MethodNotSupportedException;
 import org.apache.http.entity.ContentProducer;
@@ -23,26 +21,26 @@
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpParams;
 import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.nio.IOConsumer;
 import org.apache.http.nio.IOEventDispatch;
-import org.apache.http.nio.IOProducer;
-import org.apache.http.nio.IOSession;
 import org.apache.http.nio.IOReactor;
+import org.apache.http.nio.handler.AsyncHttpService;
+import org.apache.http.nio.handler.ContentDecoder;
+import org.apache.http.nio.handler.ContentEncoder;
+import org.apache.http.nio.handler.NHttpServerConnection;
+import org.apache.http.nio.handler.NHttpServiceHandler;
 import org.apache.http.nio.impl.DefaultIOReactor;
-import org.apache.http.nio.impl.AsyncHttpServerConnection;
+import org.apache.http.nio.impl.handler.DefaultServerIOEventDispatch;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpProcessor;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpExecutionContext;
 import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.protocol.HttpService;
+import org.apache.http.protocol.HttpRequestHandlerRegistry;
 import org.apache.http.protocol.ResponseConnControl;
 import org.apache.http.protocol.ResponseContent;
 import org.apache.http.protocol.ResponseDate;
 import org.apache.http.protocol.ResponseServer;
-import org.apache.http.protocol.SyncHttpExecutionContext;
 
 public class AsyncHttpServer {
 
@@ -59,11 +57,15 @@
             .setBooleanParameter(HttpConnectionParams.TCP_NODELAY, true)
             .setParameter(HttpProtocolParams.ORIGIN_SERVER, "Jakarta-HttpComponents-NIO/1.1");
 
-        HttpContext globalContext = new SyncHttpExecutionContext(null);
-        globalContext.setAttribute("server.docroot", args[0]);
-        
-        IOEventDispatch ioEventDispatch = new DefaultIoEventDispatch(params, globalContext);
         IOReactor ioReactor = new DefaultIOReactor(params);
+
+        // Set up request handlers
+        HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+        reqistry.register("*", new HttpFileHandler(args[0]));
+        
+        MyNHttpServiceHandler handler = new MyNHttpServiceHandler(reqistry, params);
+        IOEventDispatch ioEventDispatch = new DefaultServerIOEventDispatch(handler, params);
+        
         try {
             ioReactor.listen(new InetSocketAddress(8080));
             ioReactor.execute(ioEventDispatch);
@@ -74,93 +76,16 @@
         }
         System.out.println("Shutdown");
     }
-    
-    static class DefaultIoEventDispatch implements IOEventDispatch {
 
-        private static final String CONSUMER = "CONSUMER";
-        private static final String PRODUCER = "PRODUCER";
-        private static final String CONNECTION = "CONNECTION";
-        private static final String WORKER = "WORKER";
+    static class HttpFileHandler implements HttpRequestHandler  {
         
-        private final HttpParams params;
-        private final HttpContext context;
+        private final String docRoot;
         
-        public DefaultIoEventDispatch(final HttpParams params, final HttpContext context) {
+        public HttpFileHandler(final String docRoot) {
             super();
-            if (params == null) {
-                throw new IllegalArgumentException("HTTP parameters may nor be null");
-            }
-            this.params = params;
-            this.context = context;
-        }
-        
-        public void connected(IOSession session) {
-            AsyncHttpServerConnection conn = new AsyncHttpServerConnection(session, this.params); 
-            session.setAttribute(CONNECTION, conn);
-            session.setAttribute(CONSUMER, conn.getIOConsumer());
-            session.setAttribute(PRODUCER, conn.getIOProducer());
-            
-            // Set up HTTP service
-            BasicHttpProcessor httpProcessor = new BasicHttpProcessor();
-            httpProcessor.addInterceptor(new ResponseDate());
-            httpProcessor.addInterceptor(new ResponseServer());                    
-            httpProcessor.addInterceptor(new ResponseContent());
-            httpProcessor.addInterceptor(new ResponseConnControl());
-
-            HttpService httpService = new HttpService(
-                    httpProcessor, 
-                    new DefaultConnectionReuseStrategy(), 
-                    new DefaultHttpResponseFactory());
-            httpService.setParams(this.params);
-            httpService.registerRequestHandler("*", new HttpFileHandler());
-            
-            Thread worker = new WorkerThread(httpService, conn, this.context);
-            session.setAttribute(WORKER, worker);
-
-            worker.setDaemon(true);
-            worker.start();
-            session.setSocketTimeout(20000);
-        }
-
-        public void inputReady(final IOSession session) {
-            IOConsumer consumer = (IOConsumer) session.getAttribute(CONSUMER);
-            try {
-                consumer.consumeInput();
-            } catch (IOException ex) {
-                consumer.shutdown(ex);
-            }
-        }
-
-        public void outputReady(final IOSession session) {
-            IOProducer producer = (IOProducer) session.getAttribute(PRODUCER);
-            try {
-                producer.produceOutput();
-            } catch (IOException ex) {
-                producer.shutdown(ex);
-            }
-        }
-
-        public void timeout(final IOSession session) {
-            IOConsumer consumer = (IOConsumer) session.getAttribute(CONSUMER);
-            consumer.shutdown(new SocketTimeoutException("Socket read timeout"));
-        }
-        
-        public void disconnected(final IOSession session) {
-            HttpConnection conn = (HttpConnection) session.getAttribute(CONNECTION);
-            try {
-                conn.shutdown();
-            } catch (IOException ex) {
-                System.err.println("I/O error while shutting down connection");
-            }
-            
-            Thread worker = (Thread) session.getAttribute(WORKER);
-            worker.interrupt();
+            this.docRoot = docRoot;
         }
         
-    }
-    
-    static class HttpFileHandler implements HttpRequestHandler  {
-        
         public void handle(
                 final HttpRequest request, 
                 final HttpResponse response,
@@ -170,11 +95,9 @@
             if (!method.equalsIgnoreCase("GET") && !method.equalsIgnoreCase("HEAD")) {
                 throw new MethodNotSupportedException(method + " method not supported"); 
             }
-            String docroot = (String) context.getAttribute("server.docroot");
-            
             String target = request.getRequestLine().getUri();
             
-            final File file = new File(docroot, URLDecoder.decode(target, "UTF-8"));
+            final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8"));
             if (!file.exists()) {
 
                 response.setStatusCode(HttpStatus.SC_NOT_FOUND);
@@ -225,28 +148,132 @@
         
     }
     
+    public static class MyNHttpServiceHandler implements NHttpServiceHandler {
+        
+        private static final String HTTP_ASYNC_SERVICE = "http.async-service";
+        
+        final private HttpRequestHandlerRegistry reqistry;
+        final private HttpParams params;
+        
+        public MyNHttpServiceHandler(
+                final HttpRequestHandlerRegistry reqistry, 
+                final HttpParams params) {
+            super();
+            this.reqistry = reqistry;
+            this.params = params;
+        }
+        
+        private void shutdownConnection(final NHttpServerConnection conn) {
+            try {
+                conn.shutdown();
+            } catch (IOException ignore) {
+            }
+        }
+
+        public void connected(final NHttpServerConnection conn) {
+            // Set up the HTTP protocol processor
+            BasicHttpProcessor httpproc = new BasicHttpProcessor();
+            httpproc.addInterceptor(new ResponseDate());
+            httpproc.addInterceptor(new ResponseServer());
+            httpproc.addInterceptor(new ResponseContent());
+            httpproc.addInterceptor(new ResponseConnControl());
+
+            // Set up the HTTP service
+            AsyncHttpService httpService = new AsyncHttpService(
+                    conn,
+                    httpproc,
+                    new DefaultConnectionReuseStrategy(), 
+                    new DefaultHttpResponseFactory());
+            httpService.setParams(this.params);
+            httpService.setHandlerResolver(this.reqistry);
+            
+            conn.getContext().setAttribute(HTTP_ASYNC_SERVICE, httpService);
+        }
+
+        public void closed(final NHttpServerConnection conn) {
+            AsyncHttpService httpService = (AsyncHttpService) conn.getContext()
+                .getAttribute(HTTP_ASYNC_SERVICE);
+            httpService.shutdown();
+        }
+
+        public void exception(final NHttpServerConnection conn, final HttpException httpex) {
+            AsyncHttpService httpService = (AsyncHttpService) conn.getContext()
+                .getAttribute(HTTP_ASYNC_SERVICE);
+            try {
+                httpService.handleException(conn, httpex);
+            } catch (IOException ex) {
+                httpService.shutdown(ex);
+                shutdownConnection(conn);
+            } catch (HttpException ex) {
+                System.err.println("Unexpected HTTP protocol error: " + ex.getMessage());
+                httpService.shutdown();
+                shutdownConnection(conn);
+            }
+        }
+
+        public void exception(final NHttpServerConnection conn, final IOException ioex) {
+            AsyncHttpService httpService = (AsyncHttpService) conn.getContext()
+                .getAttribute(HTTP_ASYNC_SERVICE);
+            httpService.shutdown(ioex);
+            shutdownConnection(conn);
+        }
+
+        public void timeout(final NHttpServerConnection conn) {
+            exception(conn, new SocketTimeoutException("Socket timeout"));
+        }
+
+        public void requestReceived(final NHttpServerConnection conn) {
+            AsyncHttpService httpService = (AsyncHttpService) conn.getContext()
+                .getAttribute(HTTP_ASYNC_SERVICE);
+            
+            // BIG FAT UGLY WARNING!
+            // Do NOT start a new thread per request in real world applications!
+            // Do make sure to use a thread pool  
+            WorkerThread worker = new WorkerThread(httpService, conn); 
+            worker.setDaemon(true);
+            worker.start();
+        }
+
+        public void inputReady(final NHttpServerConnection conn, final ContentDecoder decoder) {
+            AsyncHttpService httpService = (AsyncHttpService) conn.getContext()
+                .getAttribute(HTTP_ASYNC_SERVICE);
+            try {
+                httpService.consumeContent(decoder);
+            } catch (IOException ex) {
+                httpService.shutdown(ex);
+                shutdownConnection(conn);
+            }
+        }
+
+        public void outputReady(NHttpServerConnection conn, ContentEncoder encoder) {
+            AsyncHttpService httpService = (AsyncHttpService) conn.getContext()
+                .getAttribute(HTTP_ASYNC_SERVICE);
+            try {
+                httpService.produceContent(encoder);
+            } catch (IOException ex) {
+                httpService.shutdown(ex);
+                shutdownConnection(conn);
+            }
+        }
+    }
+
     static class WorkerThread extends Thread {
 
-        private final HttpService httpservice;
-        private final HttpServerConnection conn;
-        private final HttpContext context;
+        private final AsyncHttpService httpService;
+        private final NHttpServerConnection conn;
         
         public WorkerThread(
-                final HttpService httpservice, 
-                final HttpServerConnection conn, 
-                final HttpContext parentContext) {
+                final AsyncHttpService httpService,
+                final NHttpServerConnection conn) {
             super();
-            this.httpservice = httpservice;
+            this.httpService = httpService;
             this.conn = conn;
-            this.context = new HttpExecutionContext(parentContext);
         }
         
         public void run() {
-            System.out.println("New connection thread");
+            System.out.println("New request thread");
             try {
-                while (!Thread.interrupted() && this.conn.isOpen()) {
-                    this.httpservice.handleRequest(this.conn, this.context);
-                }
+                this.httpService.handleRequest(this.conn);
             } catch (ConnectionClosedException ex) {
                 System.err.println("Client closed connection");
             } catch (IOException ex) {

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/AsyncHttpService.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/AsyncHttpService.java?view=auto&rev=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/AsyncHttpService.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/AsyncHttpService.java Sun Nov 12 08:05:03 2006
@@ -0,0 +1,251 @@
+package org.apache.http.nio.handler;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+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.ProtocolException;
+import org.apache.http.UnsupportedHttpVersionException;
+import org.apache.http.entity.BasicHttpEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.nio.impl.ContentInputBuffer;
+import org.apache.http.nio.impl.ContentInputStream;
+import org.apache.http.nio.impl.ContentOutputBuffer;
+import org.apache.http.nio.impl.ContentOutputStream;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpExecutionContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.HttpRequestHandlerResolver;
+
+public class AsyncHttpService {
+
+    private final ContentInputBuffer inbuffer; 
+    private final ContentOutputBuffer outbuffer; 
+    
+    private HttpParams params = null;
+    private HttpResponseFactory responseFactory = null;
+    private HttpProcessor httpProcessor = null;
+    private HttpRequestHandlerResolver handlerResolver = null;
+    private ConnectionReuseStrategy connStrategy = null;
+    
+    public AsyncHttpService(
+            final ContentIOControl ioControl,
+            final HttpProcessor proc,
+            final ConnectionReuseStrategy connStrategy,
+            final HttpResponseFactory responseFactory) {
+        super();
+        this.inbuffer = new ContentInputBuffer(20480, ioControl); 
+        this.outbuffer = new ContentOutputBuffer(20480, ioControl); 
+        setHttpProcessor(proc);
+        setConnReuseStrategy(connStrategy);
+        setResponseFactory(responseFactory);
+    }
+
+    public void setHttpProcessor(final HttpProcessor processor) {
+        if (processor == null) {
+            throw new IllegalArgumentException("HTTP processor may not be null.");
+        }
+        this.httpProcessor = processor;
+    }
+
+    public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) {
+        if (connStrategy == null) {
+            throw new IllegalArgumentException("Connection reuse strategy may not be null");
+        }
+        this.connStrategy = connStrategy;
+    }
+
+    public void setResponseFactory(final HttpResponseFactory responseFactory) {
+        if (responseFactory == null) {
+            throw new IllegalArgumentException("Response factory may not be null");
+        }
+        this.responseFactory = responseFactory;
+    }
+    
+    public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) {
+        this.handlerResolver = handlerResolver;
+    }
+
+    public HttpParams getParams() {
+        return this.params;
+    }
+    
+    public void setParams(final HttpParams params) {
+        this.params = params;
+    }
+    
+    public void shutdown() {
+        this.inbuffer.shutdown();
+        this.outbuffer.shutdown();
+    }
+    
+    public void shutdown(final IOException ex) {
+        this.inbuffer.shutdown(ex);
+        this.outbuffer.shutdown(ex);
+    }
+    
+    public void handleRequest(final NHttpServerConnection conn) 
+                throws HttpException, IOException {
+        // Reset buffers
+        this.inbuffer.reset();
+        this.outbuffer.reset();
+        // Get the incoming request
+        HttpContext parentContext = conn.getContext();
+        HttpRequest request = conn.getHttpRequest();
+        HttpVersion ver = request.getRequestLine().getHttpVersion();
+        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
+            // Downgrade protocol version if greater than HTTP/1.1 
+            ver = HttpVersion.HTTP_1_1;
+        }
+        if (request instanceof HttpEntityEnclosingRequest) {
+            HttpEntityEnclosingRequest entityReq = (HttpEntityEnclosingRequest) request;
+            if (entityReq.expectContinue()) {
+                HttpResponse ack = this.responseFactory.newHttpResponse(ver, 100);
+                conn.submitResponse(ack);
+            }
+            // Re-create the enclosed entity
+            HttpEntity entity = entityReq.getEntity();
+            BasicHttpEntity newEntity = new BasicHttpEntity();
+            InputStream instream = new ContentInputStream(this.inbuffer);
+            newEntity.setContent(instream);
+            newEntity.setChunked(entity.isChunked());
+            newEntity.setContentLength(entity.getContentLength());
+            newEntity.setContentType(entity.getContentType());
+            newEntity.setContentEncoding(entity.getContentEncoding());
+            
+            entityReq.setEntity(newEntity);
+        }
+        
+        // Generate response
+        request.getParams().setDefaults(this.params);
+        HttpResponse response = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_OK);
+        response.getParams().setDefaults(this.params);
+        
+        // Configure HTTP context
+        HttpContext context = new HttpExecutionContext(parentContext);
+        context.setAttribute(HttpExecutionContext.HTTP_CONNECTION, conn);
+        context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
+        context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
+        
+        try {
+            // Pre-process the request
+            this.httpProcessor.process(request, context);
+            
+            // Call HTTP request handler
+            doService(request, response, context);
+
+            // Post-process the response
+            this.httpProcessor.process(response, context);
+        } catch (HttpException ex) {
+            handleException(conn, ex);
+            return;
+        }
+
+        // Make sure the request entity is fully consumed
+        if (request instanceof HttpEntityEnclosingRequest) {
+            HttpEntityEnclosingRequest entityReq = (HttpEntityEnclosingRequest) request;
+            HttpEntity entity = entityReq.getEntity();
+            entity.consumeContent();
+        }
+        
+        // Commit the response
+        conn.submitResponse(response);
+
+        HttpEntity entity = response.getEntity();
+        if (entity != null) {
+            ContentOutputStream outstream = new ContentOutputStream(this.outbuffer);
+            entity.writeTo(outstream);
+            outstream.flush();
+        }
+
+        // Test if the connection can be reused
+        if (!this.connStrategy.keepAlive(response, context)) {
+            conn.close();
+        }
+    }
+    
+    public void handleException(final NHttpServerConnection conn, final HttpException ex)
+                throws HttpException, IOException {
+        // Reset buffers
+        this.inbuffer.reset();
+        this.outbuffer.reset();
+        // Geenrate response
+        HttpRequest request = conn.getHttpRequest();
+        HttpContext context = conn.getContext();
+        HttpVersion ver = HttpVersion.HTTP_1_1;
+        if (request != null) {
+            ver = request.getRequestLine().getHttpVersion();
+        }
+        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
+            // Downgrade protocol version if greater than HTTP/1.1 
+            ver = HttpVersion.HTTP_1_1;
+        }
+        
+        HttpResponse response = this.responseFactory.newHttpResponse(ver, HttpStatus.SC_OK);
+        response.getParams().setDefaults(this.params);
+        
+        if (ex instanceof MethodNotSupportedException) {
+            response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
+        } else if (ex instanceof UnsupportedHttpVersionException) {
+            response.setStatusCode(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED);
+        } else if (ex instanceof ProtocolException) {
+            response.setStatusCode(HttpStatus.SC_BAD_REQUEST);
+        } else {
+            response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+        }
+        StringEntity entity = new StringEntity(ex.getMessage(), "US-ASCII");
+        entity.setContentEncoding("text/plain; charset=US-ASCII");
+        response.setEntity(entity);
+        
+        // Post-process the response
+        this.httpProcessor.process(response, context);
+
+        // Commit the response
+        conn.submitResponse(response);
+        ContentOutputStream outstream = new ContentOutputStream(this.outbuffer);
+        entity.writeTo(outstream);
+        outstream.flush();
+
+        // Test if the connection can be reused
+        if (!this.connStrategy.keepAlive(response, context)) {
+            conn.close();
+        }
+    
+    }
+    
+    public void consumeContent(final ContentDecoder decoder) throws IOException {
+        this.inbuffer.consumeContent(decoder);
+    }
+
+    public void produceContent(final ContentEncoder encoder) throws IOException {
+        this.outbuffer.produceContent(encoder);
+    }
+        
+    protected void doService(
+            final HttpRequest request, 
+            final HttpResponse response,
+            final HttpContext context) throws HttpException, IOException {
+        HttpRequestHandler handler = null;
+        if (this.handlerResolver != null) {
+            String requestURI = request.getRequestLine().getUri();
+            handler = this.handlerResolver.lookup(requestURI);
+        }
+        if (handler != null) {
+            handler.handle(request, response, context);
+        } else {
+            response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED);
+        }
+    }
+    
+}

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

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

Copied: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/ContentIOControl.java (from r467445, jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java)
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/ContentIOControl.java?view=diff&rev=473977&p1=jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java&r1=467445&p2=jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/ContentIOControl.java&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/ContentIOControl.java Sun Nov 12 08:05:03 2006
@@ -29,36 +29,15 @@
 
 package org.apache.http.nio.handler;
 
-import org.apache.http.HttpConnection;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.protocol.HttpContext;
-
 /**
- * Abstract non-blocking HTTP connection interface. It can be used to request or
+ * Content input/output control interface. It can be used to request or
  * temporarily suspend event notifications that are triggered when the underlying
  * channel is ready for input / output operations. 
  * 
  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
  */
-public interface NHttpConnection extends HttpConnection {
-
-    /** 
-     * Returns the current HTTP request if one is being received / transmitted.
-     * Otherwise returns <tt>null</tt>.
-     * 
-     * @return an HTTP request if available. Otherwise returns <tt>null</tt>.
-     */
-    HttpRequest getHttpRequest();
+public interface ContentIOControl {
 
-    /** 
-     * Returns the current HTTP response if one is being received / transmitted. 
-     * Otherwise returns <tt>null</tt>.
-     * 
-     * @return an HTTP response if available. Otherwise returns <tt>null</tt>.
-     */
-    HttpResponse getHttpResponse();
-    
     /**
      * Requests event notifications to be triggered when the underlying
      * channel is ready for input oprtations.
@@ -82,11 +61,5 @@
      * ready for output operations.
      */
     void suspendOutput();
-    
-    /**
-     * Returns an HTTP execution context associated with this connection.
-     * @return HTTP context
-     */
-    HttpContext getContext();
     
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java?view=diff&rev=473977&r1=473976&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/handler/NHttpConnection.java Sun Nov 12 08:05:03 2006
@@ -35,13 +35,13 @@
 import org.apache.http.protocol.HttpContext;
 
 /**
- * Abstract non-blocking HTTP connection interface. It can be used to request or
- * temporarily suspend event notifications that are triggered when the underlying
- * channel is ready for input / output operations. 
+ * Abstract non-blocking HTTP connection interface. It contains the current
+ * HTTP context, as well as the actual HTTP request and HTTP response objects
+ * that are being received / transferred over this connection.
  * 
  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
  */
-public interface NHttpConnection extends HttpConnection {
+public interface NHttpConnection extends HttpConnection, ContentIOControl {
 
     /** 
      * Returns the current HTTP request if one is being received / transmitted.
@@ -58,30 +58,6 @@
      * @return an HTTP response if available. Otherwise returns <tt>null</tt>.
      */
     HttpResponse getHttpResponse();
-    
-    /**
-     * Requests event notifications to be triggered when the underlying
-     * channel is ready for input oprtations.
-     */
-    void requestInput();
-    
-    /**
-     * Suspends event notifications about the underlying channel being 
-     * ready for input operations.
-     */
-    void suspendInput();
-    
-    /**
-     * Requests event notifications to be triggered when the underlying
-     * channel is ready for output oprtations.
-     */
-    void requestOutput();
-    
-    /**
-     * Suspends event notifications about the underlying channel being 
-     * ready for output operations.
-     */
-    void suspendOutput();
     
     /**
      * Returns an HTTP execution context associated with this connection.

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputBuffer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputBuffer.java?view=auto&rev=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputBuffer.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputBuffer.java Sun Nov 12 08:05:03 2006
@@ -0,0 +1,174 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 1999-2006 The Apache Software Foundation
+ *
+ *  Licensed 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.impl;
+
+import java.io.IOException;
+
+import org.apache.http.nio.handler.ContentDecoder;
+import org.apache.http.nio.handler.ContentIOControl;
+
+public class ContentInputBuffer extends ExpandableBuffer {
+
+    private final ContentIOControl ioctrl;
+    private final Object mutex;
+    
+    private volatile boolean shutdown = false;
+    private volatile boolean endOfStream = false;
+    private volatile IOException exception = null;
+    
+    public ContentInputBuffer(int buffersize, final ContentIOControl ioctrl) {
+        super(buffersize);
+        if (ioctrl == null) {
+            throw new IllegalArgumentException("I/O content control may not be null");
+        }
+        this.ioctrl = ioctrl;
+        this.mutex = new Object();
+    }
+    
+    public void reset() {
+        if (this.shutdown) {
+            return;
+        }
+        synchronized (this.mutex) {
+            clear();
+            this.endOfStream = false;
+        }
+    }
+    
+    public void consumeContent(final ContentDecoder decoder) throws IOException {
+        if (this.shutdown) {
+            return;
+        }
+        synchronized (this.mutex) {
+            setInputMode();
+            int total = 0;
+            int bytesRead = 0;
+            while ((bytesRead = decoder.read(this.buffer)) > 0) {
+                total =+ bytesRead;
+            }
+            if (bytesRead == -1 || decoder.isCompleted()) {
+                this.endOfStream = true;
+            }
+            if (total > 0) {
+                this.ioctrl.suspendInput();
+                this.mutex.notifyAll();            
+            }
+        }
+    }
+    
+    protected void waitForData() throws IOException {
+        synchronized (this.mutex) {
+            try {
+                while (!hasData() && !this.endOfStream && !this.shutdown) {
+                    this.ioctrl.requestInput();
+                    this.mutex.wait();
+                }
+                IOException ex = this.exception;
+                if (ex != null) {
+                    throw ex;
+                }
+            } catch (InterruptedException ex) {
+                throw new IOException("Interrupted while waiting for more data");
+            }
+        }
+    }
+
+    public void shutdown() {
+        if (this.shutdown) {
+            return;
+        }
+        this.shutdown = true;
+        synchronized (this.mutex) {
+            this.mutex.notifyAll();
+        }
+    }
+
+    public void shutdown(final IOException exception) {
+        this.exception = exception;
+        shutdown();
+    }
+    
+    protected boolean isShutdown() {
+        return this.shutdown;
+    }
+
+    protected boolean isEndOfStream() {
+        return this.shutdown || (!hasData() && this.endOfStream);
+    }
+
+    public int read() throws IOException {
+        if (this.shutdown) {
+            return -1;
+        }
+        synchronized (this.mutex) {
+            if (!hasData()) {
+                waitForData();
+            }
+            if (isEndOfStream()) {
+                return -1; 
+            }
+            return this.buffer.get() & 0xff;
+        }
+    }
+
+    public int read(final byte[] b, int off, int len) throws IOException {
+        if (this.shutdown) {
+            return -1;
+        }
+        if (b == null) {
+            return 0;
+        }
+        synchronized (this.mutex) {
+            if (!hasData()) {
+                waitForData();
+            }
+            if (isEndOfStream()) {
+                return -1; 
+            }
+            setOutputMode();
+            int chunk = len;
+            if (chunk > this.buffer.remaining()) {
+                chunk = this.buffer.remaining();
+            }
+            this.buffer.get(b, off, chunk);
+            return chunk;
+        }
+    }
+
+    public int read(final byte[] b) throws IOException {
+        if (this.shutdown) {
+            return -1;
+        }
+        if (b == null) {
+            return 0;
+        }
+        return read(b, 0, b.length);
+    }
+
+}

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

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

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputStream.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputStream.java?view=auto&rev=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputStream.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentInputStream.java Sun Nov 12 08:05:03 2006
@@ -0,0 +1,59 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 1999-2006 The Apache Software Foundation
+ *
+ *  Licensed 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.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ContentInputStream extends InputStream {
+
+    private final ContentInputBuffer buffer;
+    
+    public ContentInputStream(final ContentInputBuffer buffer) {
+        super();
+        if (buffer == null) {
+            throw new IllegalArgumentException("Input buffer may not be null");
+        }
+        this.buffer = buffer;
+    }
+    
+    public int read(final byte[] b, int off, int len) throws IOException {
+        return this.buffer.read(b, off, len);
+    }
+    
+    public int read(final byte[] b) throws IOException {
+        return this.buffer.read(b);
+    }
+    
+    public int read() throws IOException {
+        return this.buffer.read();
+    }
+
+}

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

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

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputBuffer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputBuffer.java?view=auto&rev=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputBuffer.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputBuffer.java Sun Nov 12 08:05:03 2006
@@ -0,0 +1,169 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 1999-2006 The Apache Software Foundation
+ *
+ *  Licensed 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.impl;
+
+import java.io.IOException;
+
+import org.apache.http.nio.handler.ContentEncoder;
+import org.apache.http.nio.handler.ContentIOControl;
+
+public class ContentOutputBuffer extends ExpandableBuffer {
+    
+    private final ContentIOControl ioctrl;
+    private final Object mutex;
+    
+    private volatile boolean shutdown = false;
+    private volatile boolean endOfStream = false;
+    private volatile IOException exception = null;
+    
+    public ContentOutputBuffer(int buffersize, final ContentIOControl ioctrl) {
+        super(buffersize);
+        if (ioctrl == null) {
+            throw new IllegalArgumentException("I/O content control may not be null");
+        }
+        this.ioctrl = ioctrl;
+        this.mutex = new Object();
+    }
+
+    public void reset() {
+        if (this.shutdown) {
+            return;
+        }
+        synchronized (this.mutex) {
+            clear();
+            this.endOfStream = false;
+        }
+    }
+    
+    public void produceContent(final ContentEncoder encoder) throws IOException {
+        if (this.shutdown) {
+            return;
+        }
+        synchronized (this.mutex) {
+            setOutputMode();
+            encoder.write(this.buffer);
+            if (!hasData()) {
+                if (this.endOfStream) {
+                    encoder.complete();
+                }
+                this.ioctrl.suspendOutput();
+                this.mutex.notifyAll();            
+            }
+        }
+    }
+    
+    protected void flushBuffer() throws IOException {
+        this.ioctrl.requestOutput();
+        synchronized (this.mutex) {
+            setOutputMode();
+            try {
+                while (hasData() && !this.shutdown) {
+                    this.mutex.wait();
+                }
+
+                IOException ex = this.exception;
+                if (ex != null) {
+                    throw ex;
+                }
+                
+            } catch (InterruptedException ex) {
+                throw new IOException("Interrupted while waiting for more data");
+            }
+        }
+    }
+
+    public void shutdown() {
+        if (this.shutdown) {
+            return;
+        }
+        this.shutdown = true;
+        synchronized (this.mutex) {
+            this.mutex.notifyAll();
+        }
+    }
+
+    public void shutdown(final IOException exception) {
+        this.exception = exception;
+        shutdown();
+    }
+
+    public void write(final byte[] b, int off, int len) throws IOException {
+        if (b == null) {
+            return;
+        }
+        if (this.shutdown || this.endOfStream) {
+            return;
+        }
+        synchronized (this.mutex) {
+            setInputMode();
+            int remaining = len;
+            while (remaining > 0) {
+                if (!this.buffer.hasRemaining()) {
+                    flushBuffer();
+                    setInputMode();
+                }
+                int chunk = Math.min(remaining, this.buffer.remaining());
+                this.buffer.put(b, off, chunk);
+                remaining -= chunk;
+                off += chunk;
+            }
+        }
+    }
+
+    public void write(final byte[] b) throws IOException {
+        if (b == null) {
+            return;
+        }
+        write(b, 0, b.length);
+    }
+
+    public void write(int b) throws IOException {
+        if (this.shutdown || this.endOfStream) {
+            return;
+        }
+        synchronized (this.mutex) {
+            setInputMode();
+            if (!this.buffer.hasRemaining()) {
+                flushBuffer();
+                setInputMode();
+            }
+            this.buffer.put((byte)b);
+        }
+    }
+
+    public void flush() throws IOException {
+        flushBuffer();
+    }
+    
+    public void close() throws IOException {
+        this.endOfStream = true;
+        flushBuffer();
+    }
+    
+}

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

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

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputStream.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputStream.java?view=auto&rev=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputStream.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/ContentOutputStream.java Sun Nov 12 08:05:03 2006
@@ -0,0 +1,68 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 1999-2006 The Apache Software Foundation
+ *
+ *  Licensed 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.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class ContentOutputStream extends OutputStream {
+
+    private final ContentOutputBuffer buffer;
+    
+    public ContentOutputStream(final ContentOutputBuffer buffer) {
+        super();
+        if (buffer == null) {
+            throw new IllegalArgumentException("Output buffer may not be null");
+        }
+        this.buffer = buffer;
+    }
+
+    public void close() throws IOException {
+        this.buffer.flush();
+        this.buffer.shutdown();
+    }
+
+    public void flush() throws IOException {
+        this.buffer.flush();
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {
+        this.buffer.write(b, off, len);
+    }
+
+    public void write(byte[] b) throws IOException {
+        this.buffer.write(b);
+    }
+
+    public void write(int b) throws IOException {
+        this.buffer.write(b);
+    }
+
+}

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

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

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionInputBuffer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionInputBuffer.java?view=diff&rev=473977&r1=473976&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionInputBuffer.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionInputBuffer.java Sun Nov 12 08:05:03 2006
@@ -73,27 +73,6 @@
         return readNo;
     }
     
-    public int read(final byte[] b, int off, int len) {
-        if (b == null) {
-            return 0;
-        };
-        setOutputMode();
-        int chunk = len;
-        if (chunk > this.buffer.remaining()) {
-            chunk = this.buffer.remaining();
-        }
-        this.buffer.get(b, off, chunk);
-        return chunk;
-    }
-    
-    public int read(final byte[] b) {
-        if (b == null) {
-            return 0;
-        }
-        setOutputMode();
-        return read(b, 0, b.length);
-    }
-    
     public int read() {
         setOutputMode();
         return this.buffer.get() & 0xff;

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionOutputBuffer.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionOutputBuffer.java?view=diff&rev=473977&r1=473976&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionOutputBuffer.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/SessionOutputBuffer.java Sun Nov 12 08:05:03 2006
@@ -82,32 +82,20 @@
         this.buffer.put(src);
     }
 
-    public void write(final byte[] b, int off, int len) {
+    private void write(final byte[] b) {
         if (b == null) {
             return;
         }
         setInputMode();
+        int off = 0;
+        int len = b.length;
         int requiredCapacity = this.buffer.position() + len;
         ensureCapacity(requiredCapacity);
         this.buffer.put(b, off, len);
     }
 
-    public void write(final byte[] b) {
-        if (b == null) {
-            return;
-        }
-        write(b, 0, b.length);
-    }
-
     private void writeCRLF() {
         write(CRLF);
-    }
-
-    public void write(int b) throws IOException {
-        setInputMode();
-        int requiredCapacity = this.buffer.position() + 1;
-        ensureCapacity(requiredCapacity);
-        this.buffer.put((byte)b);
     }
 
     public void writeLine(final CharArrayBuffer linebuffer) {

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/handler/NHttpConnectionBase.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/handler/NHttpConnectionBase.java?view=diff&rev=473977&r1=473976&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/handler/NHttpConnectionBase.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/handler/NHttpConnectionBase.java Sun Nov 12 08:05:03 2006
@@ -123,27 +123,19 @@
     }
 
     public void requestInput() {
-        if (this.contentDecoder != null) {
-            this.session.setEvent(EventMask.READ);
-        }
+        this.session.setEvent(EventMask.READ);
     }
 
     public void requestOutput() {
-        if (this.contentEncoder != null) {
-            this.session.setEvent(EventMask.WRITE);
-        }
+        this.session.setEvent(EventMask.WRITE);
     }
 
     public void suspendInput() {
-        if (this.contentDecoder != null) {
-            this.session.clearEvent(EventMask.READ);
-        }
+        this.session.clearEvent(EventMask.READ);
     }
 
     public void suspendOutput() {
-        if (this.contentEncoder != null) {
-            this.session.clearEvent(EventMask.WRITE);
-        }
+        this.session.clearEvent(EventMask.WRITE);
     }
 
     protected HttpEntity prepareDecoder(final HttpMessage message) throws HttpException {

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/impl/TestSessionInOutBuffers.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/impl/TestSessionInOutBuffers.java?view=diff&rev=473977&r1=473976&r2=473977
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/impl/TestSessionInOutBuffers.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/nio/impl/TestSessionInOutBuffers.java Sun Nov 12 08:05:03 2006
@@ -31,6 +31,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.nio.channels.ReadableByteChannel;
 import java.nio.channels.WritableByteChannel;
@@ -221,12 +222,10 @@
 
     public void testComplexReadWriteLine() throws Exception {
         SessionOutputBuffer outbuf = new SessionOutputBuffer(1024, 16); 
-        outbuf.write(new byte[] {'a', '\n'});
-        outbuf.write(new byte[] {'\r', '\n'});
-        outbuf.write(new byte[] {'\r', '\r', '\n'});
-        outbuf.write(new byte[] {'\n'});
-        //these write operations should have no effect
-        outbuf.write(null, 0, 12);
+        outbuf.write(ByteBuffer.wrap(new byte[] {'a', '\n'}));
+        outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\n'}));
+        outbuf.write(ByteBuffer.wrap(new byte[] {'\r', '\r', '\n'}));
+        outbuf.write(ByteBuffer.wrap(new byte[] {'\n'}));
         
         StringBuffer buffer = new StringBuffer();
         for (int i = 0; i < 14; i++) {
@@ -234,7 +233,7 @@
         }
         String s1 = buffer.toString();
         buffer.append("\r\n");
-        outbuf.write(buffer.toString().getBytes("US-ASCII"));
+        outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes("US-ASCII")));
 
         buffer.setLength(0);
         for (int i = 0; i < 15; i++) {
@@ -242,7 +241,7 @@
         }
         String s2 = buffer.toString();
         buffer.append("\r\n");
-        outbuf.write(buffer.toString().getBytes("US-ASCII"));
+        outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes("US-ASCII")));
 
         buffer.setLength(0);
         for (int i = 0; i < 16; i++) {
@@ -250,9 +249,9 @@
         }
         String s3 = buffer.toString();
         buffer.append("\r\n");
-        outbuf.write(buffer.toString().getBytes("US-ASCII"));
+        outbuf.write(ByteBuffer.wrap(buffer.toString().getBytes("US-ASCII")));
 
-        outbuf.write(new byte[] {'a'});
+        outbuf.write(ByteBuffer.wrap(new byte[] {'a'}));
         
         ByteArrayOutputStream outstream = new ByteArrayOutputStream(); 
         WritableByteChannel outChannel = newChannel(outstream);
@@ -275,86 +274,13 @@
         assertNull(inbuf.readLine(true));
     }
     
-    public void testReadWriteBytes() throws Exception {
+    public void testReadOneByte() throws Exception {
         // make the buffer larger than that of transmitter
         byte[] out = new byte[40];
         for (int i = 0; i < out.length; i++) {
             out[i] = (byte)('0' + i);
         }
-        SessionOutputBuffer outbuf = new SessionOutputBuffer(16, 16); 
-        int off = 0;
-        int remaining = out.length;
-        while (remaining > 0) {
-            int chunk = 10;
-            if (chunk > remaining) {
-                chunk = remaining;
-            }
-            outbuf.write(out, off, chunk);
-            off += chunk;
-            remaining -= chunk;
-        }
-        
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream(); 
-        WritableByteChannel outChannel = newChannel(outstream);
-        outbuf.flush(outChannel);
-
-        byte[] tmp = outstream.toByteArray();
-        assertEquals(out.length, tmp.length);
-        for (int i = 0; i < out.length; i++) {
-            assertEquals(out[i], tmp[i]);
-        }
-        
-        ReadableByteChannel channel = newChannel(tmp);        
-        SessionInputBuffer inbuf = new SessionInputBuffer(1024, 16);
-        while (inbuf.fill(channel) > 0) {
-        }
-
-        // these read operations will have no effect
-        assertEquals(0, inbuf.read(null, 0, 10));
-        
-        byte[] in = new byte[40];
-        off = 0;
-        remaining = in.length;
-        while (remaining > 0) {
-            int chunk = 10;
-            if (chunk > remaining) {
-                chunk = remaining;
-            }
-            int l = inbuf.read(in, off, chunk);
-            if (l == -1) {
-                break;
-            }
-            off += l;
-            remaining -= l;
-        }
-        for (int i = 0; i < out.length; i++) {
-            assertEquals(out[i], in[i]);
-        }
-        assertEquals(0, inbuf.read(tmp));
-    }
-    
-    public void testReadWriteByte() throws Exception {
-        // make the buffer larger than that of transmitter
-        byte[] out = new byte[40];
-        for (int i = 0; i < out.length; i++) {
-            out[i] = (byte)('0' + i);
-        }
-        SessionOutputBuffer outbuf = new SessionOutputBuffer(16, 16); 
-        for (int i = 0; i < out.length; i++) {
-            outbuf.write(out[i]);
-        }
-
-        ByteArrayOutputStream outstream = new ByteArrayOutputStream(); 
-        WritableByteChannel outChannel = newChannel(outstream);
-        outbuf.flush(outChannel);
-
-        byte[] tmp = outstream.toByteArray();
-        assertEquals(out.length, tmp.length);
-        for (int i = 0; i < out.length; i++) {
-            assertEquals(out[i], tmp[i]);
-        }
-        
-        ReadableByteChannel channel = newChannel(tmp);        
+        ReadableByteChannel channel = newChannel(out);        
         SessionInputBuffer inbuf = new SessionInputBuffer(16, 16);
         while (inbuf.fill(channel) > 0) {
         }