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 2005/12/18 12:41:04 UTC

svn commit: r357459 - in /jakarta/httpcomponents/trunk/http-core/src: examples/org/apache/http/examples/ java/org/apache/http/ java/org/apache/http/executor/ java/org/apache/http/impl/

Author: olegk
Date: Sun Dec 18 03:40:48 2005
New Revision: 357459

URL: http://svn.apache.org/viewcvs?rev=357459&view=rev
Log:
PR #37939 - Decouple control logic (expect-continue handshake, etc) from HttpClientConnection

Modified:
    jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpGet.java
    jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpPost.java
    jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/HttpClientConnection.java
    jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/executor/HttpRequestExecutor.java
    jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
    jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultResponseStrategy.java

Modified: jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpGet.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpGet.java?rev=357459&r1=357458&r2=357459&view=diff
==============================================================================
--- jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpGet.java (original)
+++ jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpGet.java Sun Dec 18 03:40:48 2005
@@ -57,13 +57,13 @@
         Scheme.registerScheme("http", new Scheme("http", socketfactory, 80));
         
         HttpParams connparams = new DefaultHttpParams(null);
-        HttpHost host = new HttpHost("www.yahoo.com");
+        HttpHost host = new HttpHost("localhost", 8080);
         HttpClientConnection conn = new DefaultHttpClientConnection(host);
         try {
             
             String[] targets = {
                     "/",
-                    "/news/", 
+                    "/servlets-examples/servlet/RequestInfoExample", 
                     "/somewhere%20in%20pampa"};
             
             for (int i = 0; i < targets.length; i++) {
@@ -78,13 +78,8 @@
                     System.out.println("Connection kept alive. Reusing...");
                 }
                 System.out.println(">> Request URI: " + request.getRequestLine().getUri());
-                HttpResponse response = conn.sendRequest(request);
-                // Request may be terminated prematurely, when expect-continue 
-                // protocol is used
-                if (response == null) {
-                    // No error response so far. 
-                    response = conn.receiveResponse(request);
-                }
+                conn.sendRequest(request);
+                HttpResponse response = conn.receiveResponse(request.getParams()); 
                 System.out.println("<< Response: " + response.getStatusLine());
                 System.out.println(EntityUtils.toString(response.getEntity()));
                 System.out.println("==============");

Modified: jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpPost.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpPost.java?rev=357459&r1=357458&r2=357459&view=diff
==============================================================================
--- jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpPost.java (original)
+++ jakarta/httpcomponents/trunk/http-core/src/examples/org/apache/http/examples/ElementalHttpPost.java Sun Dec 18 03:40:48 2005
@@ -79,7 +79,7 @@
             };
             
             for (int i = 0; i < requestBodies.length; i++) {
-                HttpPost request = new HttpPost("/httpclienttest/body");
+                HttpPost request = new HttpPost("/servlets-examples/servlet/RequestInfoExample");
                 request.setHeader(new Header("Host", host.toHostString()));
                 request.setHeader(new Header("User-Agent", "Elemental HTTP client"));
                 request.setHeader(new Header("Connection", "Keep-Alive"));
@@ -105,13 +105,8 @@
                     System.out.println("Connection kept alive. Reusing...");
                 }
                 System.out.println(">> Request URI: " + request.getRequestLine().getUri());
-                HttpResponse response = conn.sendRequest(request);
-                // Request may be terminated prematurely, when expect-continue 
-                // protocol is used
-                if (response == null) {
-                    // No error response so far.  
-                    response = conn.receiveResponse(request);
-                }
+                conn.sendRequest(request);
+                HttpResponse response = conn.receiveResponse(request.getParams()); 
                 System.out.println("<< Response: " + response.getStatusLine());
                 System.out.println(EntityUtils.toString(response.getEntity()));
                 System.out.println("==============");

Modified: jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/HttpClientConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/HttpClientConnection.java?rev=357459&r1=357458&r2=357459&view=diff
==============================================================================
--- jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/HttpClientConnection.java (original)
+++ jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/HttpClientConnection.java Sun Dec 18 03:40:48 2005
@@ -55,8 +55,14 @@
     
     void open(HttpParams params) throws IOException;
     
-    HttpResponse sendRequest(HttpRequest request) throws HttpException, IOException;
+    void sendRequest(HttpRequest request) throws HttpException, IOException;
 
-    HttpResponse receiveResponse(HttpRequest request) throws HttpException, IOException;
+    void sendRequestHeader(HttpEntityEnclosingRequest request) throws HttpException, IOException;
+
+    void sendRequestEntity(HttpEntityEnclosingRequest request) throws HttpException, IOException;
+
+    HttpResponse receiveResponse(HttpParams params) throws HttpException, IOException;
+
+    HttpResponse receiveResponse(HttpParams params, int timeout) throws HttpException, IOException;
     
 }

Modified: jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/executor/HttpRequestExecutor.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/executor/HttpRequestExecutor.java?rev=357459&r1=357458&r2=357459&view=diff
==============================================================================
--- jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/executor/HttpRequestExecutor.java (original)
+++ jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/executor/HttpRequestExecutor.java Sun Dec 18 03:40:48 2005
@@ -30,13 +30,18 @@
 package org.apache.http.executor;
 
 import java.io.IOException;
+import java.net.ProtocolException;
 
+import org.apache.http.Header;
 import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpMutableRequest;
 import org.apache.http.HttpMutableResponse;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.AbstractHttpProcessor;
@@ -53,6 +58,10 @@
  */
 public class HttpRequestExecutor extends AbstractHttpProcessor {
 
+    private static final String EXPECT_DIRECTIVE = "Expect";
+    private static final String EXPECT_CONTINUE = "100-Continue";
+    private static final int WAIT_FOR_CONTINUE_MS = 10000;
+    
     private HttpParams params = null;
     private HttpRequestRetryHandler retryhandler = null;
     
@@ -95,7 +104,6 @@
         }
         
         HttpResponse response = null;
-        
         // loop until the method is successfully processed, the retryHandler 
         // returns false or a non-recoverable exception is thrown
         for (int execCount = 0; ; execCount++) {
@@ -111,14 +119,44 @@
                 }
                 localContext.setAttribute(HttpExecutionContext.HTTP_REQ_SENT, 
                         new Boolean(false)); 
-                response = conn.sendRequest(request);
+                HttpVersion ver = request.getRequestLine().getHttpVersion();
+                Header expect = request.getFirstHeader(EXPECT_DIRECTIVE);
+                
+                if (expect != null 
+                        && EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue())
+                        && ver.greaterEquals(HttpVersion.HTTP_1_1) 
+                        && request instanceof HttpEntityEnclosingRequest) {
+                    // Do 'expect: continue' handshake
+                    conn.sendRequestHeader((HttpEntityEnclosingRequest)request);
+                    response = conn.receiveResponse(request.getParams(), 
+                            WAIT_FOR_CONTINUE_MS);
+                    if (response == null) {
+                        // No response. The 'expect: continue' is likely not supported
+                        break;
+                    }
+                    int status = response.getStatusLine().getStatusCode();
+                    if (status < 200) {
+                        if (status != HttpStatus.SC_CONTINUE) {
+                            throw new ProtocolException("Unexpected response: " + 
+                                    response.getStatusLine());
+                        }
+                    } else {
+                        break;
+                    }                    
+                    conn.sendRequestEntity((HttpEntityEnclosingRequest)request);
+                } else {
+                    // Just fire and forget
+                    conn.sendRequest(request);
+                }
                 localContext.setAttribute(HttpExecutionContext.HTTP_REQ_SENT, 
                         new Boolean(true)); 
-                // Request may be terminated prematurely, if the expect-continue 
-                // protocol is used
-                if (response == null) {
-                    // No error response so far. 
-                    response = conn.receiveResponse(request);
+                for (;;) {
+                    // Loop until non 1xx resposne is received
+                    response = conn.receiveResponse(request.getParams());
+                    int statuscode = response.getStatusLine().getStatusCode();
+                    if (statuscode >= HttpStatus.SC_OK) {
+                        break;
+                    }
                 }
                 break;
             } catch (IOException ex) {

Modified: jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultHttpClientConnection.java?rev=357459&r1=357458&r2=357459&view=diff
==============================================================================
--- jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultHttpClientConnection.java (original)
+++ jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultHttpClientConnection.java Sun Dec 18 03:40:48 2005
@@ -45,7 +45,6 @@
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseFactory;
 import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
 import org.apache.http.NoHttpResponseException;
 import org.apache.http.ProtocolException;
 import org.apache.http.RequestLine;
@@ -71,10 +70,6 @@
 public class DefaultHttpClientConnection 
         extends AbstractHttpConnection implements HttpClientConnection {
 
-    private static final String EXPECT_DIRECTIVE = "Expect";
-    private static final String EXPECT_CONTINUE = "100-Continue";
-    private static final int WAIT_FOR_CONTINUE_MS = 10000;
-    
     private HttpHost targethost = null;
     private InetAddress localAddress = null;
 
@@ -149,7 +144,7 @@
         super.close();
     }
 
-    public HttpResponse sendRequest(final HttpRequest request) 
+    public void sendRequest(final HttpRequest request) 
             throws HttpException, IOException {
         if (request == null) {
             throw new IllegalArgumentException("HTTP request may not be null");
@@ -160,21 +155,38 @@
         
         sendRequestLine(request);
         sendRequestHeaders(request);
-        
         if (request instanceof HttpEntityEnclosingRequest) {
-            // send request may be prematurely terminated by the target server
-            HttpResponse response = expectContinue(request);
-            if (response != null) {
-                return response;
-            }
             sendRequestBody((HttpEntityEnclosingRequest)request);
         }
         this.datatransmitter.flush();
-        return null;
     }
     
-    protected void sendRequestLine(
-            final HttpRequest request) throws HttpException, IOException {
+    public void sendRequestHeader(final HttpEntityEnclosingRequest request) 
+            throws HttpException, IOException {
+        if (request == null) {
+            throw new IllegalArgumentException("HTTP request may not be null");
+        }
+        assertOpen();
+        // reset the data transmitter
+        this.datatransmitter.reset(request.getParams());
+        
+        sendRequestLine(request);
+        sendRequestHeaders(request);
+        this.datatransmitter.flush();
+    }
+
+    public void sendRequestEntity(final HttpEntityEnclosingRequest request) 
+            throws HttpException, IOException {
+        if (request == null) {
+            throw new IllegalArgumentException("HTTP request may not be null");
+        }
+        sendRequestBody(request);
+        this.datatransmitter.flush();
+    }
+
+    
+    protected void sendRequestLine(final HttpRequest request) 
+            throws HttpException, IOException {
         this.buffer.clear();
         RequestLine.format(this.buffer, request.getRequestLine());
         this.datatransmitter.writeLine(this.buffer);
@@ -183,8 +195,8 @@
         }
     }
 
-    protected void sendRequestHeaders(
-            final HttpRequest request) throws HttpException, IOException {
+    protected void sendRequestHeaders(final HttpRequest request) 
+            throws HttpException, IOException {
         Header[] headers = request.getAllHeaders();
         for (int i = 0; i < headers.length; i++) {
             this.buffer.clear();
@@ -201,33 +213,6 @@
         }
     }
 
-    protected HttpResponse expectContinue(final HttpRequest request) 
-            throws HttpException, IOException {
-        // See if 'expect-continue' handshake is supported
-        HttpVersion ver = request.getRequestLine().getHttpVersion();
-        if (ver.greaterEquals(HttpVersion.HTTP_1_1)) {
-            // ... and activated
-            Header expect = request.getFirstHeader(EXPECT_DIRECTIVE);
-            if (expect != null && EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue())) {
-                // flush the headers
-                this.datatransmitter.flush();
-                if (this.datareceiver.isDataAvailable(WAIT_FOR_CONTINUE_MS)) {
-                    HttpResponse response = readResponse(request);
-                    int status = response.getStatusLine().getStatusCode();
-                    if (status < 200) {
-                        if (status != HttpStatus.SC_CONTINUE) {
-                            throw new ProtocolException("Unexpected response: " + 
-                                    response.getStatusLine());
-                        }
-                    } else {
-                        return response;
-                    }
-                }
-            }
-        }
-        return null;
-    }
-    
     protected void sendRequestBody(final HttpEntityEnclosingRequest request) 
             throws HttpException, IOException {
         if (request.getEntity() == null) {
@@ -240,35 +225,39 @@
                 this.datatransmitter);
     }
     
-    public HttpResponse receiveResponse(final HttpRequest request) 
-                                                    throws HttpException, IOException {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
+    public HttpResponse receiveResponse(final HttpParams params) 
+            throws HttpException, IOException {
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP parameters may not be null");
         }
         assertOpen();
-
         // reset the data receiver
-        this.datareceiver.reset(request.getParams());
+        this.datareceiver.reset(params);
+        return readResponse(params);
+    }
 
-        for (;;) {
-            HttpResponse response = readResponse(request);
-            int statuscode = response.getStatusLine().getStatusCode();
-            if (statuscode >= 200) {
-                return response;
-            }
-            if (isWarnEnabled()) {
-                warn("Unexpected provisional response: " + response.getStatusLine());
-            }
+    public HttpResponse receiveResponse(final HttpParams params, int timeout) 
+            throws HttpException, IOException {
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP parameters may not be null");
+        }
+        assertOpen();
+        // reset the data receiver
+        this.datareceiver.reset(params);
+        if (this.datareceiver.isDataAvailable(timeout)) {
+            return readResponse(params);
+        } else {
+            return null;
         }
     }
 
-    protected HttpResponse readResponse(final HttpRequest request)
+    protected HttpResponse readResponse(final HttpParams params)
             throws HttpException, IOException {
-        this.datareceiver.reset(request.getParams());
-        HttpMutableResponse response = readResponseStatusLine(request.getParams());
+        this.datareceiver.reset(params);
+        HttpMutableResponse response = readResponseStatusLine(params);
         readResponseHeaders(response);
         ResponseStrategy responsestrategy = new DefaultResponseStrategy();
-        if (responsestrategy.canHaveEntity(request, response)) {
+        if (responsestrategy.canHaveEntity(null, response)) {
             readResponseBody(response);
         }
         return response;

Modified: jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultResponseStrategy.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultResponseStrategy.java?rev=357459&r1=357458&r2=357459&view=diff
==============================================================================
--- jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultResponseStrategy.java (original)
+++ jakarta/httpcomponents/trunk/http-core/src/java/org/apache/http/impl/DefaultResponseStrategy.java Sun Dec 18 03:40:48 2005
@@ -51,15 +51,14 @@
 	}
 	
     public boolean canHaveEntity(final HttpRequest request, final HttpResponse response) {
-        if (request == null) {
-            throw new IllegalArgumentException("HTTP request may not be null");
-        }
         if (response == null) {
             throw new IllegalArgumentException("HTTP response may not be null");
         }
-        String method = request.getRequestLine().getMethod();
-        if (HEAD_METHOD.equalsIgnoreCase(method)) {
-        	return false;
+        if (request != null) {
+            String method = request.getRequestLine().getMethod();
+            if (HEAD_METHOD.equalsIgnoreCase(method)) {
+                return false;
+            }
         }
         int status = response.getStatusLine().getStatusCode();
         if (status < HttpStatus.SC_OK) {