hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r168148 - in /jakarta/httpclient/trunk/http-common/src: examples/org/apache/http/examples/ java/org/apache/http/impl/ java/org/apache/http/interceptor/ java/org/apache/http/params/
Date Wed, 04 May 2005 17:12:52 GMT
Author: olegk
Date: Wed May  4 10:12:50 2005
New Revision: 168148

URL: http://svn.apache.org/viewcvs?rev=168148&view=rev
Log:
Fixed broken 'expect-continue' client-side code

Added:
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
  (with props)
Modified:
    jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java

Modified: jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java
(original)
+++ jakarta/httpclient/trunk/http-common/src/examples/org/apache/http/examples/HttpRequestExecutorDemo.java
Wed May  4 10:12:50 2005
@@ -40,6 +40,7 @@
 import org.apache.http.impl.HttpGetRequest;
 import org.apache.http.interceptor.RequestConnControl;
 import org.apache.http.interceptor.RequestContent;
+import org.apache.http.interceptor.RequestExpectContinue;
 import org.apache.http.interceptor.RequestTargetHost;
 import org.apache.http.interceptor.RequestUserAgent;
 import org.apache.http.params.HttpParams;
@@ -70,6 +71,7 @@
         // Recommended request interceptors
         httpexecutor.setRequestInterceptor(new RequestConnControl());
         httpexecutor.setRequestInterceptor(new RequestUserAgent());
+        httpexecutor.setRequestInterceptor(new RequestExpectContinue());
         
         HttpHost host = new HttpHost("www.yahoo.com");
         HttpClientConnection conn = new DefaultHttpClientConnection(host);

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
(original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpClientConnection.java
Wed May  4 10:12:50 2005
@@ -67,7 +67,7 @@
 
     private static final String EXPECT_DIRECTIVE = "Expect";
     private static final String EXPECT_CONTINUE = "100-Continue";
-    private static final int CONTINUE_WAIT_MS = 3000;
+    private static final int WAIT_FOR_CONTINUE_MS = 10000;
     
     private final HttpHost targethost;
     private final InetAddress localAddress;
@@ -166,16 +166,16 @@
             if (expect != null && EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()))
{
                 // flush the headers
                 this.datatransmitter.flush();
-                if (this.datareceiver.isDataAvailable(CONTINUE_WAIT_MS)) {
-                    HttpResponse response = receiveResponse(request);
+                if (this.datareceiver.isDataAvailable(WAIT_FOR_CONTINUE_MS)) {
+                    HttpResponse response = readResponse(request.getParams());
                     int status = response.getStatusLine().getStatusCode();
-                    if (status > 100) {
-                        return response;
-                    } else {
+                    if (status < 200) {
                         if (status != HttpStatus.SC_CONTINUE) {
                             throw new ProtocolException("Unexpected response: " + 
                                     response.getStatusLine());
                         }
+                    } else {
+                        return response;
                     }
                 }
             }
@@ -206,13 +206,30 @@
         // reset the data receiver
         this.datareceiver.reset(params);
 
-        HttpMutableResponse response = processResponseStatusLine(params);
-        processResponseHeaders(response);
-        processResponseBody(response);
+        for (;;) {
+            HttpResponse response = readResponse(params);
+            int statuscode = response.getStatusLine().getStatusCode();
+            if (statuscode >= 200) {
+                return response;
+            }
+            if (isWarnEnabled()) {
+                warn("Unexpected provisional response: " + response.getStatusLine());
+            }
+        }
+    }
+
+    protected HttpResponse readResponse(final HttpParams params)
+            throws HttpException, IOException {
+        this.datareceiver.reset(params);
+        HttpMutableResponse response = readResponseStatusLine(params);
+        readResponseHeaders(response);
+        if (canResponseHaveBody(response)) {
+            readResponseBody(response);
+        }
         return response;
     }
-    
-    protected HttpMutableResponse processResponseStatusLine(final HttpParams params) 
+
+    protected HttpMutableResponse readResponseStatusLine(final HttpParams params) 
                 throws HttpException, IOException {
         //read out the HTTP status string
         int maxGarbageLines = params.getIntParameter(
@@ -247,7 +264,7 @@
         return HttpResponseFactory.newHttpResponse(statusline);
     }
 
-    protected void processResponseHeaders(
+    protected void readResponseHeaders(
             final HttpMutableResponse response) throws HttpException, IOException {
         Header[] headers = HeadersParser.processHeaders(this.datareceiver);
         for (int i = 0; i < headers.length; i++) {
@@ -266,26 +283,17 @@
             && status != HttpStatus.SC_NOT_MODIFIED; 
     }
         
-    protected void processResponseBody(
+    protected void readResponseBody(
             final HttpMutableResponse response) throws HttpException, IOException {
         EntityGenerator entitygen = new DefaultEntityGenerator();
         HttpMutableEntity entity = entitygen.generate(this.datareceiver, response);
-        if (canResponseHaveBody(response)) {
-            // if there is a result - ALWAYS wrap it in an observer which will
-            // close the underlying stream as soon as it is consumed, and notify
-            // the watcher that the stream has been consumed.
-            InputStream instream = entity.getContent();
-            instream = new AutoCloseInputStream(
-                    instream, new DefaultResponseConsumedWatcher(this, response));
-            entity.setContent(instream);
-        } else {
-            if (entity.isChunked() || entity.getContentLength() > 0) {
-                if (isWarnEnabled()) {
-                    warn("This response may not have a response body");
-                }
-            }
-            entity.setContent(null);
-        }
+        // if there is a result - ALWAYS wrap it in an observer which will
+        // close the underlying stream as soon as it is consumed, and notify
+        // the watcher that the stream has been consumed.
+        InputStream instream = entity.getContent();
+        instream = new AutoCloseInputStream(
+                instream, new DefaultResponseConsumedWatcher(this, response));
+        entity.setContent(instream);
         response.setEntity(entity);
     }
     

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
(original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/DefaultHttpServerConnection.java
Wed May  4 10:12:50 2005
@@ -173,7 +173,7 @@
         String line = response.getStatusLine().toString();
         this.datatransmitter.writeLine(line);
         if (isWirelogEnabled()) {
-            wirelog(">> " + line + "[\\r][\\n]");
+            wirelog("<< " + line + "[\\r][\\n]");
         }
     }
 
@@ -184,12 +184,12 @@
             String line = headers[i].toString();
             this.datatransmitter.writeLine(line);
             if (isWirelogEnabled()) {
-                wirelog(">> " + line + "[\\r][\\n]");
+                wirelog("<< " + line + "[\\r][\\n]");
             }
         }
         this.datatransmitter.writeLine("");
         if (isWirelogEnabled()) {
-            wirelog(">> [\\r][\\n]");
+            wirelog("<< [\\r][\\n]");
         }
     }
 

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
(original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/impl/NIOSocketHttpDataReceiver.java
Wed May  4 10:12:50 2005
@@ -94,7 +94,8 @@
         if (hasDataInBuffer()) {
             return true;
         } else {
-            return this.selector.select(timeout) > 0;
+            this.selector.select(timeout);
+            return !this.selector.selectedKeys().isEmpty();
         }
     }    
         

Added: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java?rev=168148&view=auto
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
(added)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
Wed May  4 10:12:50 2005
@@ -0,0 +1,79 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed 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.interceptor;
+
+import java.io.IOException;
+
+import org.apache.http.Header;
+import org.apache.http.HttpContext;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpMutableRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpVersion;
+import org.apache.http.params.HttpProtocolParams;
+
+/**
+ * <p>
+ * </p>
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @version $Revision$
+ * 
+ * @since 4.0
+ */
+public class RequestExpectContinue implements HttpRequestInterceptor {
+
+    private static final String EXPECT_DIRECTIVE = "Expect";
+    
+    public RequestExpectContinue() {
+        super();
+    }
+    
+    public void process(final HttpMutableRequest request, final HttpContext context) 
+        throws HttpException, IOException {
+        if (request == null) {
+            throw new IllegalArgumentException("HTTP request may not be null");
+        }
+        if (request instanceof HttpEntityEnclosingRequest) {
+            HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
+            // Do not send the expect header if request body is known to be empty
+            if (entity != null && entity.getContentLength() != 0) { 
+                HttpProtocolParams params = new HttpProtocolParams(request.getParams());
+                HttpVersion ver = request.getRequestLine().getHttpVersion();
+                if (params.useExpectContinue() && ver.greaterEquals(HttpVersion.HTTP_1_1))
{
+                    request.addHeader(new Header(EXPECT_DIRECTIVE, "100-Continue", true));
+                }
+            }
+        }
+    }
+    
+}

Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/interceptor/RequestExpectContinue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java?rev=168148&r1=168147&r2=168148&view=diff
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java
(original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/params/HttpProtocolParams.java
Wed May  4 10:12:50 2005
@@ -133,6 +133,34 @@
      */
     public static final String STRICT_TRANSFER_ENCODING = "http.protocol.strict-transfer-encoding";

 
+    /**
+     * <p>
+     * Activates 'Expect: 100-Continue' handshake for the 
+     * {@link org.apache.commons.httpclient.methods.ExpectContinueMethod 
+     * entity enclosing methods}. The purpose of the 'Expect: 100-Continue'
+     * handshake to allow a client that is sending a request message with 
+     * a request body to determine if the origin server is willing to 
+     * accept the request (based on the request headers) before the client
+     * sends the request body.
+     * </p>
+     * 
+     * <p>
+     * The use of the 'Expect: 100-continue' handshake can result in 
+     * noticable peformance improvement for entity enclosing requests
+     * (such as POST and PUT) that require the target server's 
+     * authentication.
+     * </p>
+     * 
+     * <p>
+     * 'Expect: 100-continue' handshake should be used with 
+     * caution, as it may cause problems with HTTP servers and 
+     * proxies that do not support HTTP/1.1 protocol.
+     * </p>
+     * 
+     * This parameter expects a value of type {@link Boolean}.
+     */
+    public static final String USE_EXPECT_CONTINUE = "http.protocol.expect-continue"; 
+
     private final HttpParams params;
     
     /**
@@ -303,4 +331,11 @@
         return setParameter(USER_AGENT, useragent);
     }
 
+    public boolean useExpectContinue() {
+        return getBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+    }
+    
+    public HttpProtocolParams setUseExpectContinue(boolean b) {
+        return setBooleanParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, b);
+    }
 }



Mime
View raw message