hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r499542 - 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/impl/ main/java/org/apache/http/nio/impl/entity/ main/java/org/apache/ht...
Date Wed, 24 Jan 2007 19:40:56 GMT
Author: olegk
Date: Wed Jan 24 11:40:55 2007
New Revision: 499542

URL: http://svn.apache.org/viewvc?view=rev&rev=499542
Log:
Major changes in the client-side NIO protocol layer in preparation for resolution of HTTPCORE-26

Changelog:
* Added an interface intended to be used to control the execution of HTTP requests on the
client side
* Added an HTTP client handler implementation that buffers the content of HTTP messages entirely
in memory and executes HTTP requests on the main I/O thread.

Added:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
  (with props)
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
  (with props)
Modified:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpClientHandler.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/DefaultNHttpClientConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/NHttpConnectionBase.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/entity/BufferedContent.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java?view=diff&rev=499542&r1=499541&r2=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/examples/org/apache/http/nio/examples/NHttpClient.java
Wed Jan 24 11:40:55 2007
@@ -1,30 +1,23 @@
 package org.apache.http.nio.examples;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InterruptedIOException;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.WritableByteChannel;
 
-import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpConnection;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestFactory;
 import org.apache.http.HttpResponse;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpParams;
-import org.apache.http.impl.DefaultHttpRequestFactory;
-import org.apache.http.nio.ContentDecoder;
-import org.apache.http.nio.ContentEncoder;
-import org.apache.http.nio.NHttpClientConnection;
-import org.apache.http.nio.NHttpClientHandler;
+import org.apache.http.message.HttpGet;
 import org.apache.http.nio.impl.DefaultClientIOEventDispatch;
 import org.apache.http.nio.impl.reactor.DefaultConnectingIOReactor;
+import org.apache.http.nio.protocol.BufferingHttpClientHandler;
+import org.apache.http.nio.protocol.EventListener;
+import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOEventDispatch;
 import org.apache.http.nio.reactor.SessionRequest;
@@ -32,10 +25,8 @@
 import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.BasicHttpProcessor;
-import org.apache.http.protocol.HTTP;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExecutionContext;
-import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
 import org.apache.http.protocol.RequestContent;
 import org.apache.http.protocol.RequestExpectContinue;
@@ -71,7 +62,21 @@
                 null,
                 new HttpHost("www.apache.org"));
 
-        NHttpClientHandler handler = new MyNHttpClientHandler(reqs, params);
+        BasicHttpProcessor httpproc = new BasicHttpProcessor();
+        httpproc.addInterceptor(new RequestContent());
+        httpproc.addInterceptor(new RequestTargetHost());
+        httpproc.addInterceptor(new RequestConnControl());
+        httpproc.addInterceptor(new RequestUserAgent());
+        httpproc.addInterceptor(new RequestExpectContinue());
+        
+        BufferingHttpClientHandler handler = new BufferingHttpClientHandler(
+                httpproc,
+                new MyHttpRequestExecutionHandler(),
+                new DefaultConnectionReuseStrategy(),
+                params);
+
+        handler.setEventListener(new EventLogger());
+        
         IOEventDispatch ioEventDispatch = new DefaultClientIOEventDispatch(handler, params);
         
         try {
@@ -84,151 +89,74 @@
         System.out.println("Shutdown");
     }
     
-    static class MyNHttpClientHandler implements NHttpClientHandler {
+    static class MyHttpRequestExecutionHandler implements HttpRequestExecutionHandler {
 
-        private final SessionRequest[] reqs;
-        private final HttpParams params;
-        private final HttpRequestFactory requestFactory; 
-        private final HttpProcessor httpProcessor;
-        private final ByteBuffer inbuf;
-        private final ConnectionReuseStrategy connStrategy;
-        
-        private int connCount = 0;
-        
-        public MyNHttpClientHandler(final SessionRequest[] reqs, final HttpParams params)
{
-            super();
-            this.reqs = reqs;
-            this.params = params;
-            this.requestFactory = new DefaultHttpRequestFactory();
-            BasicHttpProcessor httpproc = new BasicHttpProcessor();
-            httpproc.addInterceptor(new RequestContent());
-            httpproc.addInterceptor(new RequestTargetHost());
-            httpproc.addInterceptor(new RequestConnControl());
-            httpproc.addInterceptor(new RequestUserAgent());
-            httpproc.addInterceptor(new RequestExpectContinue());
-            this.httpProcessor = httpproc;
-            this.inbuf = ByteBuffer.allocateDirect(2048);
-            this.connStrategy = new DefaultConnectionReuseStrategy();
+        public void initalizeContext(final HttpContext context, final Object attachment)
{
+            HttpHost targetHost = (HttpHost) attachment;
+            context.setAttribute(HttpExecutionContext.HTTP_TARGET_HOST, targetHost);
         }
-        
-        private void shutdownConnection(final HttpConnection conn) {
-            try {
-                conn.shutdown();
-            } catch (IOException ignore) {
+
+        public HttpRequest submitRequest(final HttpContext context) {
+            HttpHost targetHost = (HttpHost) context.getAttribute(
+                    HttpExecutionContext.HTTP_TARGET_HOST);
+            Integer countObj = (Integer) context.getAttribute(
+                    "request-count");
+            int counter = 0; 
+            if (countObj != null) {
+                counter = countObj.intValue(); 
+            }
+            counter++;
+            context.setAttribute("request-count", new Integer(counter));
+            if (counter < 3) {
+                System.out.println("--------------");
+                System.out.println("Sending request to " + targetHost);
+                System.out.println("--------------");
+                return new HttpGet("/");
+            } else {
+                // Return null to terminate the connection
+                return null;
             }
         }
         
-        public void connected(final NHttpClientConnection conn, final Object attachment)
{
+        public void handleResponse(final HttpResponse response, final HttpContext context)
{
+            HttpEntity entity = response.getEntity();
             try {
-                HttpContext context = conn.getContext();
-                
-                HttpHost targetHost = (HttpHost) attachment;
-                
-                context.setAttribute(HttpExecutionContext.HTTP_CONNECTION, conn);
-                context.setAttribute(HttpExecutionContext.HTTP_TARGET_HOST, targetHost);
+                String content = EntityUtils.toString(entity);
                 
-                HttpRequest request = this.requestFactory.newHttpRequest("GET", "/");
-                request.getParams().setDefaults(this.params);
-                
-                this.httpProcessor.process(request, context);
-                
-                conn.submitRequest(request);
-
-                context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
-            
+                System.out.println("--------------");
+                System.out.println(response.getStatusLine());
+                System.out.println("--------------");
+                System.out.println("Document length: " + content.length());
+                System.out.println("--------------");
             } catch (IOException ex) {
-                shutdownConnection(conn);
                 System.err.println("I/O error: " + ex.getMessage());
-            } catch (HttpException ex) {
-                shutdownConnection(conn);
-                System.err.println("Unexpected HTTP protocol error: " + ex.getMessage());
-            }
-        }
-
-        public void closed(final NHttpClientConnection conn) {
-            System.out.println("Connection closed");
-            this.connCount++;
-            if (this.connCount >= this.reqs.length) {
-                System.exit(0);
             }
         }
+        
+    }
+    
+    static class EventLogger implements EventListener {
 
-        public void exception(final NHttpClientConnection conn, final HttpException ex) {
-            System.err.println("HTTP protocol error: " + ex.getMessage());
-            shutdownConnection(conn);
-        }
-
-        public void exception(final NHttpClientConnection conn, final IOException ex) {
-            System.err.println("I/O error: " + ex.getMessage());
-            shutdownConnection(conn);
+        public void connectionOpen(final InetAddress address) {
+            System.out.println("Connection open: " + address);
         }
 
-        public void inputReady(final NHttpClientConnection conn, final ContentDecoder decoder)
{
-            HttpResponse response = conn.getHttpResponse();
-            HttpContext context = conn.getContext();
-            HttpHost targetHost = (HttpHost) context
-                .getAttribute(HttpExecutionContext.HTTP_TARGET_HOST);
-            WritableByteChannel channel = (WritableByteChannel) context
-                .getAttribute("in-channel");
-
-            try {
-                while (decoder.read(this.inbuf) > 0) {
-                    this.inbuf.flip();
-                    channel.write(this.inbuf);
-                    this.inbuf.compact();
-                }
-                if (decoder.isCompleted()) {
-                    HttpEntity entity = response.getEntity();
-                    
-                    ByteArrayOutputStream bytestream = (ByteArrayOutputStream) context
-                        .getAttribute("in-buffer");
-                    byte[] content = bytestream.toByteArray();
-                    
-                    String charset = EntityUtils.getContentCharSet(entity);
-                    if (charset == null) {
-                        charset = HTTP.DEFAULT_CONTENT_CHARSET;
-                    }
-                    
-                    System.out.println("--------------");
-                    System.out.println("Target: " + targetHost);
-                    System.out.println("--------------");
-                    System.out.println(response.getStatusLine());
-                    System.out.println("--------------");
-                    System.out.println(new String(content, charset));
-                    System.out.println("--------------");
-
-                    if (!this.connStrategy.keepAlive(response, context)) {
-                        conn.close();
-                    }
-                }
-                
-            } catch (IOException ex) {
-                shutdownConnection(conn);
-                System.err.println("I/O error: " + ex.getMessage());
-            }
+        public void connectionTimeout(final InetAddress address) {
+            System.out.println("Connection timed out: " + address);
         }
 
-        public void outputReady(final NHttpClientConnection conn, final ContentEncoder encoder)
{
+        public void connectionClosed(InetAddress address) {
+            System.out.println("Connection closed: " + address);
         }
 
-        public void responseReceived(final NHttpClientConnection conn) {
-            HttpResponse response = conn.getHttpResponse();
-            
-            if (response.getStatusLine().getStatusCode() >= 200) {
-                ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
-                WritableByteChannel channel = Channels.newChannel(bytestream);
-                
-                HttpContext context = conn.getContext();
-                context.setAttribute("in-buffer", bytestream);
-                context.setAttribute("in-channel", channel);
-            }
+        public void fatalIOException(IOException ex) {
+            System.err.println("I/O error: " + ex.getMessage());
         }
 
-        public void timeout(final NHttpClientConnection conn) {
-            System.err.println("Timeout");
-            shutdownConnection(conn);
+        public void fatalProtocolException(HttpException ex) {
+            System.err.println("HTTP error: " + ex.getMessage());
         }
         
-    } 
-    
+    }
+        
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpClientHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpClientHandler.java?view=diff&rev=499542&r1=499541&r2=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpClientHandler.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpClientHandler.java
Wed Jan 24 11:40:55 2007
@@ -52,6 +52,15 @@
     void connected(NHttpClientConnection conn, Object attachment);
     
     /**
+     * Triggered when the connection is ready to send an HTTP request.
+     * 
+     * @see NHttpClientConnection
+     * 
+     * @param conn HTTP connection that contains an HTTP response
+     */
+    void requestReady(NHttpClientConnection conn);
+
+    /**
      * Triggered when an HTTP response is received. The connection
      * passed as a parameter to this method is guaranteed to return
      * a valid HTTP response object.

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/DefaultNHttpClientConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/DefaultNHttpClientConnection.java?view=diff&rev=499542&r1=499541&r2=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/DefaultNHttpClientConnection.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/DefaultNHttpClientConnection.java
Wed Jan 24 11:40:55 2007
@@ -150,6 +150,10 @@
             // Finally set buffered output flag
             this.hasBufferedOutput = this.contentEncoder != null && this.outbuf.hasData();
         }
+
+        if (this.request == null && !this.closed) {
+            handler.requestReady(this);
+        }
     }
     
     public void submitRequest(final HttpRequest request) throws HttpException {
@@ -179,8 +183,8 @@
 
         if (request instanceof HttpEntityEnclosingRequest) {
             prepareEncoder(request);
+            this.request = request;
         }
-        this.request = request;
         this.session.setEvent(EventMask.WRITE);
     }
 

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/NHttpConnectionBase.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/NHttpConnectionBase.java?view=diff&rev=499542&r1=499541&r2=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/NHttpConnectionBase.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/NHttpConnectionBase.java
Wed Jan 24 11:40:55 2007
@@ -134,27 +134,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/main/java/org/apache/http/nio/impl/entity/BufferedContent.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/entity/BufferedContent.java?view=diff&rev=499542&r1=499541&r2=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/entity/BufferedContent.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/impl/entity/BufferedContent.java
Wed Jan 24 11:40:55 2007
@@ -34,6 +34,7 @@
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpResponse;
 import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.nio.impl.ContentInputBuffer;
 
@@ -47,6 +48,7 @@
         if (entity == null) {
             throw new IllegalArgumentException("HTTP entity may not be null");
         }
+        this.wrappedEntity = entity;
         setContent(new ContentInputStream(buffer));
     }
 
@@ -72,8 +74,22 @@
         if (request == null) {
             throw new IllegalArgumentException("HTTP request may not be null");
         }
-        BufferedContent entity = new BufferedContent(request.getEntity(), buffer); 
-        request.setEntity(entity);
+        if (request.getEntity() != null) {
+            BufferedContent entity = new BufferedContent(request.getEntity(), buffer); 
+            request.setEntity(entity);
+        }
+    }
+
+    public static void wrapEntity(
+            final HttpResponse response, 
+            final ContentInputBuffer buffer) {
+        if (response == null) {
+            throw new IllegalArgumentException("HTTP response may not be null");
+        }
+        if (response.getEntity() != null) {
+            BufferedContent entity = new BufferedContent(response.getEntity(), buffer); 
+            response.setEntity(entity);
+        }
     }
     
 }

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java?view=auto&rev=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
(added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
Wed Jan 24 11:40:55 2007
@@ -0,0 +1,353 @@
+/*
+ * $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.protocol;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetAddress;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpConnection;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpInetConnection;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.nio.ContentDecoder;
+import org.apache.http.nio.ContentEncoder;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.NHttpClientHandler;
+import org.apache.http.nio.impl.InputBuffer;
+import org.apache.http.nio.impl.OutputBuffer;
+import org.apache.http.nio.impl.entity.BufferedContent;
+import org.apache.http.nio.impl.entity.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;
+
+/**
+ * HTTP client handler implementation that buffers the content of HTTP messages 
+ * entirely in memory and executes HTTP requests on the main I/O thread.
+ * 
+ * <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 BufferingHttpClientHandler implements NHttpClientHandler {
+
+    private static final String IN_BUF = "http.nio.in-buffer";
+    private static final String OUT_BUF = "http.nio.out-buffer";
+    
+    private HttpParams params;
+    private HttpProcessor httpProcessor;
+    private HttpRequestExecutionHandler execHandler;
+    private ConnectionReuseStrategy connStrategy;
+    private EventListener eventListener;
+    
+    public BufferingHttpClientHandler(
+            final HttpProcessor httpProcessor, 
+            final HttpRequestExecutionHandler execHandler,
+            final ConnectionReuseStrategy connStrategy,
+            final HttpParams params) {
+        super();
+        if (httpProcessor == null) {
+            throw new IllegalArgumentException("HTTP processor may not be null.");
+        }
+        if (execHandler == null) {
+            throw new IllegalArgumentException("HTTP request execution handler may not be
null.");
+        }
+        if (connStrategy == null) {
+            throw new IllegalArgumentException("Connection reuse strategy may not be null");
+        }
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP parameters may not be null");
+        }
+        this.httpProcessor = httpProcessor;
+        this.execHandler = execHandler;
+        this.connStrategy = connStrategy;
+        this.params = params;
+    }
+    
+    public void setEventListener(final EventListener eventListener) {
+        this.eventListener = eventListener;
+    }
+
+    private void shutdownConnection(final HttpConnection conn) {
+        try {
+            conn.shutdown();
+        } catch (IOException ignore) {
+        }
+    }
+    
+    public void connected(final NHttpClientConnection conn, final Object attachment) {
+        HttpContext context = conn.getContext();
+
+        initialize(conn, attachment);
+        
+        InputBuffer inbuffer = new InputBuffer(2048); 
+        OutputBuffer outbuffer = new OutputBuffer(2048);
+        
+        context.setAttribute(IN_BUF, inbuffer);
+        context.setAttribute(OUT_BUF, outbuffer);
+
+        if (this.eventListener != null) {
+            InetAddress address = null;
+            if (conn instanceof HttpInetConnection) {
+                address = ((HttpInetConnection) conn).getRemoteAddress();
+            }
+            this.eventListener.connectionOpen(address);
+        }
+        
+        requestReady(conn);        
+    }
+
+    public void closed(final NHttpClientConnection conn) {
+        if (this.eventListener != null) {
+            InetAddress address = null;
+            if (conn instanceof HttpInetConnection) {
+                address = ((HttpInetConnection) conn).getRemoteAddress();
+            }
+            this.eventListener.connectionClosed(address);
+        }
+    }
+
+    public void exception(final NHttpClientConnection conn, final HttpException ex) {
+        shutdownConnection(conn);
+        if (this.eventListener != null) {
+            this.eventListener.fatalProtocolException(ex);
+        }
+    }
+
+    public void exception(final NHttpClientConnection conn, final IOException ex) {
+        shutdownConnection(conn);
+        if (this.eventListener != null) {
+            this.eventListener.fatalIOException(ex);
+        }
+    }
+    
+    public void requestReady(final NHttpClientConnection conn) {
+        HttpContext context = conn.getContext();
+
+        OutputBuffer outbuffer = (OutputBuffer) context.getAttribute(OUT_BUF);
+
+        try {
+            
+            submitRequest(conn, outbuffer);                
+            
+        } catch (IOException ex) {
+            shutdownConnection(conn);
+            if (this.eventListener != null) {
+                this.eventListener.fatalIOException(ex);
+            }
+        } catch (HttpException ex) {
+            shutdownConnection(conn);
+            if (this.eventListener != null) {
+                this.eventListener.fatalProtocolException(ex);
+            }
+        }
+    }
+
+    public void inputReady(final NHttpClientConnection conn, final ContentDecoder decoder)
{
+        HttpContext context = conn.getContext();
+
+        InputBuffer inbuffer = (InputBuffer) context.getAttribute(IN_BUF);
+        OutputBuffer outbuffer = (OutputBuffer) context.getAttribute(OUT_BUF);
+
+        try {
+            
+            inbuffer.consumeContent(decoder);
+            if (decoder.isCompleted()) {
+
+                processResponse(conn, inbuffer);
+                // Clean up buffers just in case
+                inbuffer.clear();
+                outbuffer.clear();
+                // Ready for another request
+                conn.requestOutput();                
+            }
+            
+        } catch (IOException ex) {
+            shutdownConnection(conn);
+            if (this.eventListener != null) {
+                this.eventListener.fatalIOException(ex);
+            }
+        } catch (HttpException ex) {
+            shutdownConnection(conn);
+            if (this.eventListener != null) {
+                this.eventListener.fatalProtocolException(ex);
+            }
+        }
+    }
+
+    public void outputReady(final NHttpClientConnection conn, final ContentEncoder encoder)
{
+        HttpContext context = conn.getContext();
+        OutputBuffer outbuffer = (OutputBuffer) context.getAttribute(OUT_BUF);
+
+        try {
+            
+            outbuffer.produceContent(encoder);
+            
+        } catch (IOException ex) {
+            shutdownConnection(conn);
+            if (this.eventListener != null) {
+                this.eventListener.fatalIOException(ex);
+            }
+        }
+    }
+
+    public void responseReceived(final NHttpClientConnection conn) {
+        HttpContext context = conn.getContext();
+        HttpResponse response = conn.getHttpResponse();
+        HttpRequest request = (HttpRequest) context.getAttribute(
+                HttpExecutionContext.HTTP_REQUEST);
+
+        InputBuffer inbuffer = (InputBuffer) context.getAttribute(IN_BUF);
+        OutputBuffer outbuffer = (OutputBuffer) context.getAttribute(OUT_BUF);
+        
+        if (response.getStatusLine().getStatusCode() < HttpStatus.SC_OK) {
+            // Just ignore 1xx responses;
+            return;
+        }
+        
+        if (!canResponseHaveBody(request, response)) {
+            try {
+                
+                processResponse(conn, inbuffer);
+                // Clean up buffers just in case
+                inbuffer.clear();
+                outbuffer.clear();
+                // Ready for another request
+                conn.requestOutput();                
+                
+            } catch (IOException ex) {
+                shutdownConnection(conn);
+                if (this.eventListener != null) {
+                    this.eventListener.fatalIOException(ex);
+                }
+            } catch (HttpException ex) {
+                shutdownConnection(conn);
+                if (this.eventListener != null) {
+                    this.eventListener.fatalProtocolException(ex);
+                }
+            }
+        }
+    }
+
+    public void timeout(final NHttpClientConnection conn) {
+        shutdownConnection(conn);
+        if (this.eventListener != null) {
+            InetAddress address = null;
+            if (conn instanceof HttpInetConnection) {
+                address = ((HttpInetConnection) conn).getRemoteAddress();
+            }
+            this.eventListener.connectionTimeout(address);
+        }
+    }
+    
+    private void initialize(
+            final NHttpClientConnection conn,
+            final Object attachment) {
+        HttpContext context = conn.getContext();
+
+        context.setAttribute(HttpExecutionContext.HTTP_CONNECTION, conn);
+        this.execHandler.initalizeContext(context, attachment);
+    }
+    
+    private void submitRequest(
+            final NHttpClientConnection conn, 
+            final OutputBuffer outbuffer) throws IOException, HttpException {
+        
+        HttpContext context = conn.getContext();
+        HttpRequest request = this.execHandler.submitRequest(context);
+        if (request == null) {
+            return;
+        }
+        
+        request.getParams().setDefaults(this.params);
+        
+        context.setAttribute(HttpExecutionContext.HTTP_REQUEST, request);
+
+        this.httpProcessor.process(request, context);
+        
+        conn.submitRequest(request);
+        
+        if (request instanceof HttpEntityEnclosingRequest) {
+            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+            if (entity != null) {
+                OutputStream outstream = new ContentOutputStream(outbuffer);
+                entity.writeTo(outstream);
+                outstream.flush();
+            }
+        }
+        
+    }
+    
+    protected boolean canResponseHaveBody(
+            final HttpRequest request, final HttpResponse response) {
+
+        if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
+            return false;
+        }
+        
+        int status = response.getStatusLine().getStatusCode(); 
+        return status >= HttpStatus.SC_OK 
+            && status != HttpStatus.SC_NO_CONTENT 
+            && status != HttpStatus.SC_NOT_MODIFIED
+            && status != HttpStatus.SC_RESET_CONTENT; 
+    }
+    
+    private void processResponse(
+            final NHttpClientConnection conn, 
+            final InputBuffer inbuffer) throws IOException, HttpException {
+
+        HttpContext context = conn.getContext();
+        HttpResponse response = conn.getHttpResponse();
+        // Create a wrapper entity instead of the original one
+        BufferedContent.wrapEntity(response, inbuffer);
+        
+        context.setAttribute(HttpExecutionContext.HTTP_RESPONSE, response);
+        
+        this.httpProcessor.process(response, context);
+        
+        this.execHandler.handleResponse(response, context);
+        
+        if (!this.connStrategy.keepAlive(response, context)) {
+            conn.close();
+        }
+        
+    }
+}
\ No newline at end of file

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

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

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java?view=diff&rev=499542&r1=499541&r2=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
(original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
Wed Jan 24 11:40:55 2007
@@ -367,9 +367,11 @@
 
         if (response.getEntity() != null) {
             HttpEntity entity = response.getEntity();
-            OutputStream outstream = new ContentOutputStream(outbuffer);
-            entity.writeTo(outstream);
-            outstream.flush();
+            if (entity != null) {
+                OutputStream outstream = new ContentOutputStream(outbuffer);
+                entity.writeTo(outstream);
+                outstream.flush();
+            }
         }
     }
 

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java?view=auto&rev=499542
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
(added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/HttpRequestExecutionHandler.java
Wed Jan 24 11:40:55 2007
@@ -0,0 +1,87 @@
+/*
+ * $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.protocol;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.nio.reactor.ConnectingIOReactor;
+import org.apache.http.protocol.HttpContext;
+
+/**
+ * HTTP request execution handler can be used by client-side protocol handlers 
+ * to trigger the submission of a new HTTP request and the processing of an 
+ * HTTP response.
+ * 
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ */
+public interface HttpRequestExecutionHandler {
+
+    /**
+     * Triggered when a new connection has been established and the 
+     * HTTP context needs to be initialized. 
+     * 
+     * <p>The attachment object is the same object which was passed 
+     * to the connecting I/O reactor when the connection request was 
+     * made. The attachment may optionally contain some state information
+     * required in order to correctly initalize the HTTP context.
+     * 
+     * @see ConnectingIOReactor#connect(java.net.SocketAddress, java.net.SocketAddress, Object)
+     * 
+     * @param context the actual HTTP context
+     * @param attachment the object passed to the connecting I/O reactor
+     *   upon the request for a new connection.
+     */
+    void initalizeContext(HttpContext context, Object attachment);
+
+    /**
+     * Triggered when the underlying connection is ready to send a new 
+     * HTTP request to the target host. This method may return 
+     * <code>null</null> if the client is not yet ready to send a
+     * request. In this case the connection will remain open and
+     * can be activated at a later point.
+     * 
+     * @param context the actual HTTP context
+     * @return an HTTP request to be sent or <code>null</null> if no
+     *   request needs to be sent
+     */
+    HttpRequest submitRequest(HttpContext context);
+    
+    /**
+     * Triggered when an HTTP response is ready to be processed.
+     * 
+     * @param response the HTTP response to be processed
+     * @param context the actual HTTP context
+     */
+    void handleResponse(HttpResponse response, HttpContext context);
+    
+}

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

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



Mime
View raw message