You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ri...@apache.org on 2008/02/07 14:05:01 UTC

svn commit: r619394 - in /geronimo/sandbox/AsyncHttpClient/src: main/java/org/apache/ahc/codec/HttpDecoder.java main/java/org/apache/ahc/codec/HttpResponseDecoder.java test/java/org/apache/ahc/AbstractTest.java

Author: rickmcguire
Date: Thu Feb  7 05:04:59 2008
New Revision: 619394

URL: http://svn.apache.org/viewvc?rev=619394&view=rev
Log:
GERONIMO-3824 ProtocolDecoderException is thrown if the response does not specify Content-Length but is not chunked

Patch provided by Sangjin Lee


Modified:
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpDecoder.java
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpResponseDecoder.java
    geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java

Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpDecoder.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpDecoder.java?rev=619394&r1=619393&r2=619394&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpDecoder.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpDecoder.java Thu Feb  7 05:04:59 2008
@@ -224,15 +224,49 @@
     }
 
     /**
-     * Decodes content from non-chunked transcoding.
+     * Decodes content from non-chunked transcoding.  It adds exactly the amount
+     * of data specified in the content length header.
      * 
-     * @param in the <code>ByteBuffer</code> containing the content at the the current position
-     * @param msg the <code>HttpResponseMessage</code> message to place the decoded content
+     * @param in the <code>ByteBuffer</code> containing the content at the the 
+     * current position
+     * @param msg the <code>HttpResponseMessage</code> message to place the 
+     * decoded content
      * 
      * @throws Exception if any exception occurs
      */
     public void decodeContent(ByteBuffer in, HttpResponseMessage msg) throws Exception {
-        byte content[] = new byte[msg.getContentLength()];
+        addContent(in, msg, msg.getContentLength());
+    }
+    
+    /**
+     * Decodes content from non-chunked transcoding.  It adds all the remaining
+     * bytes from the buffer into the response body.
+     * 
+     * @param in the <code>ByteBuffer</code> containing the content at the
+     * current position
+     * @param msg the <code>HttpResponseMessage</code> message to place the 
+     * decoded content
+     * 
+     * @throws Exception if any exception occurs
+     */
+    public void decodeRemainingContent(ByteBuffer in, HttpResponseMessage msg) throws Exception {
+        if (in.hasRemaining()) {
+            addContent(in, msg, in.remaining());
+        }
+    }
+    
+    /**
+     * Transfer a specific size of content from the buffer 
+     * to the message. 
+     * 
+     * @param in     The input buffer
+     * @param msg    The message that will receive the content.
+     * @param size   The number of bytes to transfer.
+     * 
+     * @exception Exception
+     */
+    private void addContent(ByteBuffer in, HttpResponseMessage msg, int size) throws Exception {
+        byte[] content = new byte[size];
         in.get(content);
         msg.addContent(content);
     }

Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpResponseDecoder.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpResponseDecoder.java?rev=619394&r1=619393&r2=619394&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpResponseDecoder.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpResponseDecoder.java Thu Feb  7 05:04:59 2008
@@ -115,11 +115,7 @@
                 }
             }
 
-            response.setState(HttpResponseMessage.STATE_FINISHED);
-
-            out.write(response);
-
-            ioSession.removeAttribute(HttpIoHandler.CURRENT_RESPONSE);
+            completeResponse(ioSession, out, response);
 
             return true;
         } catch (NeedMoreDataException e) {
@@ -127,6 +123,28 @@
         }
     }
 
+    @Override
+    public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
+        // if the response was still being decoded when the session is getting
+        // closed, we finish decoding and hand off the response
+        HttpResponseMessage response = 
+                (HttpResponseMessage)session.getAttribute(HttpIoHandler.CURRENT_RESPONSE);
+        // we're only interested in non-chunked responses with no content length
+        // specified, in which case connection close marks the end of the body
+        if (response != null &&
+                !response.isChunked() &&
+                response.getContentLength() <= 0 &&
+                response.getState() == HttpResponseMessage.STATE_HEADERS_READ) {
+            completeResponse(session, out, response);
+        }
+    }
+
+    private void completeResponse(IoSession ioSession, ProtocolDecoderOutput out, HttpResponseMessage response) {
+        response.setState(HttpResponseMessage.STATE_FINISHED);
+        out.write(response);
+        ioSession.removeAttribute(HttpIoHandler.CURRENT_RESPONSE);
+    }
+
     /**
      * Reads the headers and processes them as header objects in the {@link HttpResponseMessage} object.
      * 
@@ -249,6 +267,12 @@
                 return false;
             }
             httpDecoder.decodeContent(in, response);
+        } else {
+            // it neither is chunked nor has content length; read until the
+            // session closes
+            httpDecoder.decodeRemainingContent(in, response);
+            // keep looping until the session closes
+            return false;
         }
 
         response.setState(HttpResponseMessage.STATE_CONTENT_READ);

Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java?rev=619394&r1=619393&r2=619394&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java Thu Feb  7 05:04:59 2008
@@ -144,7 +144,6 @@
 
         public void onClosed() {
             closed = true;
-            System.out.println("onClosed()");
         }
 
         public void onTimeout() {
@@ -192,7 +191,7 @@
         }
         
         public void await(int timeout, TimeUnit unit) throws InterruptedException {
-        	complete.await(timeout, unit);
+            complete.await(timeout, unit);
         }
     }
 }