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 2007/02/21 18:52:36 UTC

svn commit: r510119 - in /jakarta/httpcomponents/httpcore/trunk: module-main/src/main/java/org/apache/http/ module-main/src/main/java/org/apache/http/impl/ module-main/src/test/java/org/apache/http/impl/ module-main/src/test/java/org/apache/http/mockup...

Author: olegk
Date: Wed Feb 21 09:52:36 2007
New Revision: 510119

URL: http://svn.apache.org/viewvc?view=rev&rev=510119
Log:
HTTPCORE-42: 

* Moved socket timeout methods to the HttpConnection interface
* Added the 'expect: continue' handshake support to the buffering HTTP client handler

Modified:
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/mockup/HttpConnectionMockup.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpConnection.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ClientConnState.java

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java Wed Feb 21 09:52:36 2007
@@ -77,6 +77,22 @@
     public boolean isStale();
     
     /**
+     * Sets the socket timeout value.
+     * 
+     * @param timeout timeout value in milliseconds
+     */
+    void setSocketTimeout(int timeout);
+    
+    /**
+     * Returns the socket timeout value.
+     * 
+     * @return positive value in milliseconds if a timeout is set, 
+     * <code>0</code> if timeout is disabled or <code>-1</code> if 
+     * timeout is undefined.
+     */
+    int getSocketTimeout();
+
+    /**
      * Force-closes this connection.
      * This is the only method of a connection which may be called
      * from a different thread to terminate the connection. 

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpClientConnection.java Wed Feb 21 09:52:36 2007
@@ -144,13 +144,31 @@
         }
     }
 
-    public void setSocketTimeout(int timeout) throws SocketException {
+    public void setSocketTimeout(int timeout) {
         assertOpen();
         if (this.socket != null) {
-            this.socket.setSoTimeout(timeout);
+            try {
+                this.socket.setSoTimeout(timeout);
+            } catch (SocketException ignore) {
+                // It is not quite clear from the Sun's documentation if there are any 
+                // other legitimate cases for a socket exception to be thrown when setting 
+                // SO_TIMEOUT besides the socket being already closed
+            }
         }
     }
     
+    public int getSocketTimeout() {
+        if (this.socket != null) {
+            try {
+                return this.socket.getSoTimeout();
+            } catch (SocketException ignore) {
+                return -1;
+            }
+        } else {
+            return -1;
+        }
+    }
+
     public void shutdown() throws IOException {
         this.open = false;
         Socket tmpsocket = this.socket;

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/SocketHttpServerConnection.java Wed Feb 21 09:52:36 2007
@@ -142,13 +142,31 @@
         }
     }
 
-    public void setSocketTimeout(int timeout) throws SocketException {
+    public void setSocketTimeout(int timeout) {
         assertOpen();
         if (this.socket != null) {
-            this.socket.setSoTimeout(timeout);
+            try {
+                this.socket.setSoTimeout(timeout);
+            } catch (SocketException ignore) {
+                // It is not quite clear from the Sun's documentation if there are any 
+                // other legitimate cases for a socket exception to be thrown when setting 
+                // SO_TIMEOUT besides the socket being already closed
+            }
         }
     }
     
+    public int getSocketTimeout() {
+        if (this.socket != null) {
+            try {
+                return this.socket.getSoTimeout();
+            } catch (SocketException ignore) {
+                return -1;
+            }
+        } else {
+            return -1;
+        }
+    }
+
     public void shutdown() throws IOException {
         this.open = false;
         Socket tmpsocket = this.socket;

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/impl/TestDefaultConnectionReuseStrategy.java Wed Feb 21 09:52:36 2007
@@ -292,6 +292,13 @@
             return iAmOpen;
         }
 
+        public void setSocketTimeout(int timeout) {
+        }
+
+        public int getSocketTimeout() {
+            return -1;
+        }
+
         public final boolean isStale() {
             return iAmStale;
         }
@@ -305,6 +312,7 @@
             throw new UnsupportedOperationException
                 ("connection state must not be modified");
         }
+        
     } // class MockConnection
 
 } // class TestDefaultConnectionReuseStrategy

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/mockup/HttpConnectionMockup.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/mockup/HttpConnectionMockup.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/mockup/HttpConnectionMockup.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/mockup/HttpConnectionMockup.java Wed Feb 21 09:52:36 2007
@@ -56,8 +56,11 @@
         this.open = false;
     }
     
-    public int getSocketTimeout() throws IOException {
-        return 0;
+    public void setSocketTimeout(int timeout) {
+    }
+
+    public int getSocketTimeout() {
+        return -1;
     }
     
     public boolean isOpen() {
@@ -68,6 +71,4 @@
         return false;
     }
 
-    public void setSocketTimeout(int timeout) throws IOException {
-    }
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/NHttpConnectionBase.java Wed Feb 21 09:52:36 2007
@@ -259,6 +259,10 @@
         this.session.setSocketTimeout(timeout);
     }
 
+    public int getSocketTimeout() {
+        return this.session.getSocketTimeout();
+    }
+
     public void shutdown() throws IOException {
         this.closed = true;
         this.session.close();

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpConnection.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpConnection.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpConnection.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/NHttpConnection.java Wed Feb 21 09:52:36 2007
@@ -67,11 +67,4 @@
      */
     HttpContext getContext();
     
-    /**
-     * Sets socket timeout value.
-     * 
-     * @param timeout timeout value in milliseconds
-     */
-    void setSocketTimeout(int timeout);
-    
 }

Modified: 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=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpClientHandler.java Wed Feb 21 09:52:36 2007
@@ -54,6 +54,7 @@
 import org.apache.http.nio.util.SimpleInputBuffer;
 import org.apache.http.nio.util.SimpleOutputBuffer;
 import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExecutionContext;
 import org.apache.http.protocol.HttpProcessor;
@@ -207,9 +208,6 @@
 
                 connState.setInputState(ClientConnState.RESPONSE_BODY_DONE);
                 processResponse(conn, connState);
-                // Ready for another request
-                connState.resetInput();
-                conn.requestOutput();
                 
             }
             
@@ -253,42 +251,61 @@
 
     public void responseReceived(final NHttpClientConnection conn) {
         HttpContext context = conn.getContext();
-        HttpResponse response = conn.getHttpResponse();
-
         ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
-        
-        connState.setResponse(response);
-        connState.setInputState(ClientConnState.RESPONSE_RECEIVED);
+
+        HttpResponse response = conn.getHttpResponse();
         HttpRequest request = connState.getRequest();
         
-        if (response.getStatusLine().getStatusCode() < HttpStatus.SC_OK) {
-            // Just ignore 1xx responses;
-            return;
-        }
-        
-        if (!canResponseHaveBody(request, response)) {
-            try {
-                
-                processResponse(conn, connState);
-                // Ready for another request
-                connState.resetOutput();
-                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);
+        try {
+            
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode < HttpStatus.SC_OK) {
+                // 1xx intermediate response
+                if (statusCode == HttpStatus.SC_CONTINUE 
+                        && connState.getOutputState() == ClientConnState.EXPECT_CONTINUE) {
+                    continueRequest(conn, connState);
                 }
+                return;
+            } else {
+                connState.setResponse(response);
+                connState.setInputState(ClientConnState.RESPONSE_RECEIVED);
+            }
+            
+            if (!canResponseHaveBody(request, response)) {
+                processResponse(conn, connState);
+            }
+            
+        } 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) {
+        HttpContext context = conn.getContext();
+        ClientConnState connState = (ClientConnState) context.getAttribute(CONN_STATE);
+
+        try {
+            
+            if (connState.getOutputState() == ClientConnState.EXPECT_CONTINUE) {
+                continueRequest(conn, connState);
+                return;
+            }
+            
+        } catch (IOException ex) {
+            shutdownConnection(conn);
+            if (this.eventListener != null) {
+                this.eventListener.fatalIOException(ex);
+            }
+        }
+        
         shutdownConnection(conn);
         if (this.eventListener != null) {
             InetAddress address = null;
@@ -329,17 +346,45 @@
         connState.setOutputState(ClientConnState.REQUEST_SENT);
         
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
-            if (entity != null) {
-                OutputStream outstream = new ContentOutputStream(connState.getOutbuffer());
-                entity.writeTo(outstream);
-                outstream.flush();
-                outstream.close();
+            if (((HttpEntityEnclosingRequest) request).expectContinue()) {
+                int timeout = conn.getSocketTimeout();
+                connState.setTimeout(timeout);
+                timeout = this.params.getIntParameter(
+                        HttpProtocolParams.WAIT_FOR_CONTINUE, 3000);
+                conn.setSocketTimeout(timeout);
+                connState.setOutputState(ClientConnState.EXPECT_CONTINUE);
+            } else {
+                prepareRequestBody((HttpEntityEnclosingRequest) request, connState);
             }
         }
     }
     
-    protected boolean canResponseHaveBody(
+    private void continueRequest(
+            final NHttpClientConnection conn, 
+            final ClientConnState connState) throws IOException {
+
+        HttpRequest request = connState.getRequest();
+
+        int timeout = connState.getTimeout();
+        conn.setSocketTimeout(timeout);
+
+        prepareRequestBody((HttpEntityEnclosingRequest) request, connState);
+        connState.setOutputState(ClientConnState.REQUEST_SENT);
+    }
+    
+    private void prepareRequestBody(
+            final HttpEntityEnclosingRequest request,
+            final ClientConnState connState) throws IOException {
+        HttpEntity entity = request.getEntity();
+        if (entity != null) {
+            OutputStream outstream = new ContentOutputStream(connState.getOutbuffer());
+            entity.writeTo(outstream);
+            outstream.flush();
+            outstream.close();
+        }
+    }
+    
+    private boolean canResponseHaveBody(
             final HttpRequest request, final HttpResponse response) {
 
         if (request != null && "HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
@@ -358,7 +403,8 @@
             final ClientConnState connState) throws IOException, HttpException {
 
         HttpContext context = conn.getContext();
-        HttpResponse response = conn.getHttpResponse();
+        HttpResponse response = connState.getResponse();
+        
         // Create a wrapper entity instead of the original one
         if (response.getEntity() != null) {
             response.setEntity(new BufferedContent(
@@ -374,8 +420,12 @@
         
         if (!this.connStrategy.keepAlive(response, context)) {
             conn.close();
+            connState.shutdown();
+        } else {
+            // Ready for another request
+            connState.resetInput();
+            conn.requestOutput();
         }
-        
     }
     
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ClientConnState.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ClientConnState.java?view=diff&rev=510119&r1=510118&r2=510119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ClientConnState.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ClientConnState.java Wed Feb 21 09:52:36 2007
@@ -64,6 +64,8 @@
     private volatile HttpRequest request;
     private volatile HttpResponse response;
 
+    private int timeout;
+    
     public ClientConnState(
             final ContentInputBuffer inbuffer,
             final ContentOutputBuffer outbuffer) {
@@ -118,6 +120,14 @@
         this.response = response;
     }
 
+    public int getTimeout() {
+        return this.timeout;
+    }
+
+    public void setTimeout(int timeout) {
+        this.timeout = timeout;
+    }
+        
     public void shutdown() {
         this.inbuffer.shutdown();
         this.outbuffer.shutdown();
@@ -136,5 +146,5 @@
         this.request = null;
         this.outputState = READY;
     }
-        
+
 }



Re: [HttpCore] Home for socket timeout; was Re: svn commit: r510119

Posted by Roland Weber <ht...@dubioso.net>.
Hi Oleg,

> Will renaming xxxSocketTimeout to xxxIOTimeout be an improvement? One
> way or another we need a generic means of handling connection I/O
> timeouts for the client side of the 'expect: continue' handshake.

Let's leave it as it is. Otherwise we'll just have to point more
users to those methods. With setSocketTimeout as the name, they'll
find it themselves.

cheers,
  Roland


---------------------------------------------------------------------
To unsubscribe, e-mail: httpcomponents-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpcomponents-dev-help@jakarta.apache.org


[HttpCore] Home for socket timeout; was Re: svn commit: r510119

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Wed, 2007-02-21 at 19:08 +0100, Roland Weber wrote:
> Hi Oleg,
> 
> > HTTPCORE-42: 
> > 
> > * Moved socket timeout methods to the HttpConnection interface
> 
> I was quite satisfied that our generic connection interfaces had
> nothing to do with sockets. As is it just in the method names and
> does not actually reference the Socket class I'm still OK with this
> change. Just wanted to put it on record.
> 
> cheers,
>   Roland
> 

Hi Roland

Will renaming xxxSocketTimeout to xxxIOTimeout be an improvement? One
way or another we need a generic means of handling connection I/O
timeouts for the client side of the 'expect: continue' handshake.

Oleg

> > +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java Wed Feb 21 09:52:36 2007
> > @@ -77,6 +77,22 @@
> > +    void setSocketTimeout(int timeout);
> > +    int getSocketTimeout();
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpcomponents-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: httpcomponents-dev-help@jakarta.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: httpcomponents-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpcomponents-dev-help@jakarta.apache.org


Re: svn commit: r510119 - in /jakarta/httpcomponents/httpcore/trunk: module-main/src/main/java/org/apache/http/ module-main/src/main/java/org/apache/http/impl/ module-main/src/test/java/org/apache/http/impl/ module-main/src/test/java/org/apache/http/mockup...

Posted by Roland Weber <ht...@dubioso.net>.
Hi Oleg,

> HTTPCORE-42: 
> 
> * Moved socket timeout methods to the HttpConnection interface

I was quite satisfied that our generic connection interfaces had
nothing to do with sockets. As is it just in the method names and
does not actually reference the Socket class I'm still OK with this
change. Just wanted to put it on record.

cheers,
  Roland

> +++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpConnection.java Wed Feb 21 09:52:36 2007
> @@ -77,6 +77,22 @@
> +    void setSocketTimeout(int timeout);
> +    int getSocketTimeout();


---------------------------------------------------------------------
To unsubscribe, e-mail: httpcomponents-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpcomponents-dev-help@jakarta.apache.org