geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickmcgu...@apache.org
Subject svn commit: r630189 - in /geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc: AsyncHttpClient.java codec/HttpIoHandler.java codec/HttpMessage.java codec/HttpResponseDecoder.java proxy/ProxyFilter.java
Date Fri, 22 Feb 2008 13:02:32 GMT
Author: rickmcguire
Date: Fri Feb 22 05:02:23 2008
New Revision: 630189

URL: http://svn.apache.org/viewvc?rev=630189&view=rev
Log:
GERONIMO-3872 proxy connect for https tunneling times out

Patch provided by Sangjin Lee


Modified:
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpResponseDecoder.java
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java

Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java?rev=630189&r1=630188&r2=630189&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java Fri
Feb 22 05:02:23 2008
@@ -873,6 +873,8 @@
                 // write the connect request if the protocol is https
                 String protocol = request.getUrl().getProtocol();
                 if (protocol.toLowerCase().equals("https")) {
+                    // add a connect handshake pending flag to the session
+                    session.setAttribute(HttpIoHandler.PROXY_CONNECT_IN_PROGRESS);
                     session.write(createConnectRequest());
                 } else {
                     session.write(request);

Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java?rev=630189&r1=630188&r2=630189&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java
(original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java
Fri Feb 22 05:02:23 2008
@@ -55,6 +55,11 @@
     public static final String CURRENT_RESPONSE = "CURRENT_RESPONSE";
     
     /**
+     * The Constant for the proxy connect status.
+     */
+    public static final String PROXY_CONNECT_IN_PROGRESS = "PROXY_CONNECT_IN_PROGRESS";
+    
+    /**
      * The Constant CONNECTION_CLOSE.
      */
     public static final String CONNECTION_CLOSE = "close";

Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java?rev=630189&r1=630188&r2=630189&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpMessage.java Fri
Feb 22 05:02:23 2008
@@ -57,7 +57,7 @@
     protected String contentType;
     
     /** The content length. */
-    protected int contentLength;
+    protected int contentLength = -1;
     
     /** The content container. */
     protected ByteArrayOutputStream 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=630189&r1=630188&r2=630189&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
Fri Feb 22 05:02:23 2008
@@ -103,7 +103,7 @@
 
             //Are we reading content?
             if (response.getState() == HttpResponseMessage.STATE_HEADERS_READ) {
-                if (!processContent(response, in)) {
+                if (!processContent(response, ioSession, in)) {
                     throw new NeedMoreDataException();
                 }
             }
@@ -219,12 +219,12 @@
      * 
      * @param response the {@link HttpResponseMessage} response object
      * @param in the <code>ByteBuffer</code> that contains the raw bytes from
the server
-     * 
      * @return <code>true</code> if it can read all of the data, or <code>false</code>
if not.
      * 
      * @throws Exception if any exception occurs
      */
-    private boolean processContent(HttpResponseMessage response, ByteBuffer in) throws Exception
{
+    private boolean processContent(HttpResponseMessage response, IoSession session, ByteBuffer
in) 
+            throws Exception {
         if (response.isChunked()) {
             while (true) {
                 //Check what kind of record we are reading (content or size)
@@ -267,7 +267,7 @@
                 return false;
             }
             httpDecoder.decodeContent(in, response);
-        } else {
+        } else if (!noContentExpected(session, response)) {
             // it neither is chunked nor has content length; read until the
             // session closes
             httpDecoder.decodeRemainingContent(in, response);
@@ -278,6 +278,32 @@
         response.setState(HttpResponseMessage.STATE_CONTENT_READ);
 
         return true;
+    }
+    
+    /**
+     * Returns whether content is not expected for this response.  Responses
+     * with certain status codes must not have contents, as well as responses to
+     * proxy connect requests.
+     */
+    private boolean noContentExpected(IoSession session, HttpResponseMessage response) {
+        int status = response.getStatusCode();
+        // if status is no content or not modified, content is not allowed
+        if (status == 204 || status == 304) {
+            return true;
+        }
+        
+        // explicit 0 content length
+        if (response.getContentLength() == 0) {
+            return true;
+        }
+        
+        // proxy connect handshake is in progress, in which case the connection
+        // will be persistent but no content is expected
+        if (session.getAttribute(HttpIoHandler.PROXY_CONNECT_IN_PROGRESS) != null) {
+            return true;
+        }
+        
+        return false;
     }
 
     /**

Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java?rev=630189&r1=630188&r2=630189&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/proxy/ProxyFilter.java Fri
Feb 22 05:02:23 2008
@@ -12,7 +12,6 @@
 public class ProxyFilter extends IoFilterAdapter {
     public static final String PROXY_AUTHORIZATION_HEADER = "Proxy-Authorization";
     
-    private volatile boolean connectHandshakeComplete;
     private final SSLFilter sslFilter;
 
     /**
@@ -93,7 +92,7 @@
      */
     public void messageReceived(NextFilter nextFilter, IoSession session,
             Object message) throws Exception {
-        if (needConnectHandshake()) {
+        if (connectInProgress(session)) {
             // we need to complete the connect handshake
             handleConnectResponse(session, message);
         } else {
@@ -104,15 +103,15 @@
     }
     
     /**
-     * Tests if we need to perform the SSL tunneling handshake. 
-     * If this is an https request, we need to handle the 
-     * tunneling here.  If we've already established this, 
-     * then the processing can continue with the next filter. 
+     * Tests if we are performing the connect handshake for SSL tunneling.  If 
+     * this is an https request, we need to handle the tunneling here.  If we've 
+     * already established this, then the processing can continue with the next 
+     * filter. 
      * 
-     * @return true if we need to establish the handshake.
+     * @return true if the connect handshake is in progress.
      */
-    private boolean needConnectHandshake() {
-        return (sslFilter != null && !connectHandshakeComplete);
+    private boolean connectInProgress(IoSession session) {
+        return session.getAttribute(HttpIoHandler.PROXY_CONNECT_IN_PROGRESS) != null;
     }
 
     /**
@@ -131,7 +130,8 @@
         if (status == 200) {
             // layer the SSL socket by inserting the SSL filter
             session.getFilterChain().addBefore(AsyncHttpClient.PROTOCOL_FILTER, "SSL", sslFilter);
-            connectHandshakeComplete = true; // handshake is done
+            // handshake is done
+            session.removeAttribute(HttpIoHandler.PROXY_CONNECT_IN_PROGRESS);
             HttpRequestMessage request = getRequest(session);
             // write the original request intended for the remote target
             session.write(request);



Mime
View raw message