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/13 18:53:27 UTC

svn commit: r507119 - in /jakarta/httpcomponents/httpcore/trunk: module-main/src/main/java/org/apache/http/impl/params/ module-main/src/main/java/org/apache/http/params/ module-main/src/main/java/org/apache/http/protocol/ module-nio/src/main/java/org/a...

Author: olegk
Date: Tue Feb 13 09:53:26 2007
New Revision: 507119

URL: http://svn.apache.org/viewvc?view=rev&rev=507119
Log:
HTTPCORE-42: Added HttpExpectationVerifier interface and updated all server side HTTP services to make use of this interface during the expect:100-continue handshake to verify whether incoming requests satisfy the target server's expectations

Added:
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java   (with props)
Removed:
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/impl/params/
Modified:
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/params/HttpProtocolParams.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java
    jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
    jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java
    jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
    jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/params/HttpProtocolParams.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/params/HttpProtocolParams.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/params/HttpProtocolParams.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/params/HttpProtocolParams.java Tue Feb 13 09:53:26 2007
@@ -143,6 +143,16 @@
     public static final String USE_EXPECT_CONTINUE = "http.protocol.expect-continue"; 
 
     /**
+     * <p>
+     * Defines the maximum period of time in milliseconds the client should spend
+     * waiting for a 100-continue response.
+     * </p>
+     * 
+     * This parameter expects a value of type {@link Integer}.
+     */
+    public static final String WAIT_FOR_CONTINUE = "http.protocol.wait-for-continue";
+    
+    /**
      */
     private HttpProtocolParams() {
         super();

Added: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java?view=auto&rev=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java Tue Feb 13 09:53:26 2007
@@ -0,0 +1,73 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.protocol;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+
+/**
+ * Defines an interface to verify whether an incoming HTTP request meets 
+ * the target server's expectations. 
+ *<p>
+ * The Expect request-header field is used to indicate that particular
+ * server behaviors are required by the client.
+ *</p>
+ *<pre>
+ *    Expect       =  "Expect" ":" 1#expectation
+ *
+ *    expectation  =  "100-continue" | expectation-extension
+ *    expectation-extension =  token [ "=" ( token | quoted-string )
+ *                             *expect-params ]
+ *    expect-params =  ";" token [ "=" ( token | quoted-string ) ]
+ *</pre>
+ *<p>
+ * A server that does not understand or is unable to comply with any of
+ * the expectation values in the Expect field of a request MUST respond
+ * with appropriate error status. The server MUST respond with a 417
+ * (Expectation Failed) status if any of the expectations cannot be met
+ * or, if there are other problems with the request, some other 4xx
+ * status.
+ *</p>
+ *
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ *
+ * @version $Revision$
+ * 
+ * @since 4.0
+ */
+public interface HttpExpectationVerifier {
+
+    void verify(HttpRequest request, HttpResponse response, HttpContext context)
+            throws HttpException;
+    
+}

Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpExpectationVerifier.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpRequestExecutor.java Tue Feb 13 09:53:26 2007
@@ -42,6 +42,7 @@
 import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
 import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
 
 /**
  * Sends HTTP requests and receives the responses.
@@ -56,9 +57,6 @@
  */
 public class HttpRequestExecutor {
 
-    //TODO make this value customizable, just use this as a default
-    protected static final int WAIT_FOR_CONTINUE_MS = 10000;
-
     private HttpParams params;
     private final HttpProcessor processor;
 
@@ -231,28 +229,26 @@
 
         conn.sendRequestHeader(request);
         if (request instanceof HttpEntityEnclosingRequest) {
-            HttpEntityEnclosingRequest entityEnclRequest =
-                (HttpEntityEnclosingRequest) request;
-
             // Check for expect-continue handshake. We have to flush the
             // headers and wait for an 100-continue response to handle it.
             // If we get a different response, we must not send the entity.
             boolean sendentity = true;
             final HttpVersion ver = request.getRequestLine().getHttpVersion();
-            if (entityEnclRequest.expectContinue() &&
+            if (((HttpEntityEnclosingRequest) request).expectContinue() &&
                 ver.greaterEquals(HttpVersion.HTTP_1_1)) {
 
                 conn.flush();
                 // As suggested by RFC 2616 section 8.2.3, we don't wait for a
                 // 100-continue response forever. On timeout, send the entity.
-                if (conn.isResponseAvailable(WAIT_FOR_CONTINUE_MS)) {
+                int tms = params.getIntParameter(HttpProtocolParams.WAIT_FOR_CONTINUE, 2000);
+                
+                if (conn.isResponseAvailable(tms)) {
                     response = conn.receiveResponseHeader(request.getParams());
                     if (canResponseHaveBody(request, response)) {
                         conn.receiveResponseEntity(response);
                     }
                     int status = response.getStatusLine().getStatusCode();
                     if (status < 200) {
-                        //@@@ TODO: is this in line with RFC 2616, 10.1?
                         if (status != HttpStatus.SC_CONTINUE) {
                             throw new ProtocolException(
                                     "Unexpected response: " + response.getStatusLine());
@@ -265,7 +261,7 @@
                 }
             }
             if (sendentity) {
-                conn.sendRequestEntity(entityEnclRequest);
+                conn.sendRequestEntity((HttpEntityEnclosingRequest) request);
             }
         }
         conn.flush();

Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/protocol/HttpService.java Tue Feb 13 09:53:26 2007
@@ -62,6 +62,7 @@
     private HttpRequestHandlerResolver handlerResolver = null;
     private ConnectionReuseStrategy connStrategy = null;
     private HttpResponseFactory responseFactory = null;
+    private HttpExpectationVerifier expectationVerifier = null;
     
     /**
      * Create a new HTTP service.
@@ -105,6 +106,10 @@
         this.handlerResolver = handlerResolver;
     }
 
+    public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
+        this.expectationVerifier = expectationVerifier;
+    }
+
     public HttpParams getParams() {
         return this.params;
     }
@@ -134,6 +139,9 @@
                     HttpResponse ack = this.responseFactory.newHttpResponse
                         (ver, HttpStatus.SC_CONTINUE, context);
                     ack.getParams().setDefaults(this.params);
+                    if (this.expectationVerifier != null) {
+                        this.expectationVerifier.verify(request, ack, context);
+                    }
                     conn.sendResponseHeader(ack);
                     conn.flush();
                 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/BufferingHttpServiceHandler.java Tue Feb 13 09:53:26 2007
@@ -59,6 +59,7 @@
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExecutionContext;
+import org.apache.http.protocol.HttpExpectationVerifier;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.apache.http.protocol.HttpRequestHandlerResolver;
@@ -84,6 +85,7 @@
     private HttpResponseFactory responseFactory;
     private ConnectionReuseStrategy connStrategy;
     private HttpRequestHandlerResolver handlerResolver;
+    private HttpExpectationVerifier expectationVerifier;
     private EventListener eventListener;
     
     public BufferingHttpServiceHandler(
@@ -118,6 +120,10 @@
         this.handlerResolver = handlerResolver;
     }
 
+    public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
+        this.expectationVerifier = expectationVerifier;
+    }
+
     public HttpParams getParams() {
         return this.params;
     }
@@ -143,7 +149,12 @@
     public void requestReceived(final NHttpServerConnection conn) {
         HttpContext context = conn.getContext();
         HttpRequest request = conn.getHttpRequest();
+
         HttpVersion ver = request.getRequestLine().getHttpVersion();
+        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
+            // Downgrade protocol version if greater than HTTP/1.1 
+            ver = HttpVersion.HTTP_1_1;
+        }
 
         InputBuffer inbuffer = (InputBuffer) context.getAttribute(IN_BUF);
         OutputBuffer outbuffer = (OutputBuffer) context.getAttribute(OUT_BUF);
@@ -156,7 +167,12 @@
 
             if (request instanceof HttpEntityEnclosingRequest) {
                 if (((HttpEntityEnclosingRequest) request).expectContinue()) {
-                    HttpResponse ack = this.responseFactory.newHttpResponse(ver, 100, context);
+                    HttpResponse ack = this.responseFactory.newHttpResponse(
+                            ver, HttpStatus.SC_CONTINUE, context);
+                    ack.getParams().setDefaults(this.params);
+                    if (this.expectationVerifier != null) {
+                        this.expectationVerifier.verify(request, ack, context);
+                    }
                     conn.submitResponse(ack);
                 }
                 // Request content is expected. 

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/protocol/ThrottlingHttpServiceHandler.java Tue Feb 13 09:53:26 2007
@@ -61,6 +61,7 @@
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpExecutionContext;
+import org.apache.http.protocol.HttpExpectationVerifier;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.HttpRequestHandler;
 import org.apache.http.protocol.HttpRequestHandlerResolver;
@@ -93,6 +94,7 @@
     private HttpResponseFactory responseFactory;
     private ConnectionReuseStrategy connStrategy;
     private HttpRequestHandlerResolver handlerResolver;
+    private HttpExpectationVerifier expectationVerifier;
     private EventListener eventListener;
     private Executor executor;
     
@@ -133,6 +135,10 @@
         this.handlerResolver = handlerResolver;
     }
 
+    public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) {
+        this.expectationVerifier = expectationVerifier;
+    }
+
     public HttpParams getParams() {
         return this.params;
     }
@@ -228,6 +234,12 @@
         final HttpContext context = conn.getContext();
         final HttpRequest request = conn.getHttpRequest();
 
+        HttpVersion ver = request.getRequestLine().getHttpVersion();
+        if (!ver.lessEquals(HttpVersion.HTTP_1_1)) {
+            // Downgrade protocol version if greater than HTTP/1.1 
+            ver = HttpVersion.HTTP_1_1;
+        }
+
         SharedInputBuffer inbuffer = (SharedInputBuffer) context.getAttribute(IN_BUF);
         SharedOutputBuffer outbuffer = (SharedOutputBuffer) context.getAttribute(OUT_BUF);
 
@@ -237,9 +249,13 @@
 
         if (request instanceof HttpEntityEnclosingRequest) {
             if (((HttpEntityEnclosingRequest) request).expectContinue()) {
-                HttpVersion ver = request.getRequestLine().getHttpVersion();
-                HttpResponse ack = this.responseFactory.newHttpResponse(ver, 100, context);
                 try {
+                    HttpResponse ack = this.responseFactory.newHttpResponse(
+                            ver, HttpStatus.SC_CONTINUE, context);
+                    ack.getParams().setDefaults(this.params);
+                    if (this.expectationVerifier != null) {
+                        this.expectationVerifier.verify(request, ack, context);
+                    }
                     conn.submitResponse(ack);
                 } catch (HttpException ex) {
                     shutdownConnection(conn);

Modified: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLClientIOEventDispatch.java Tue Feb 13 09:53:26 2007
@@ -131,7 +131,7 @@
                 if (sslSession.isAppOutputReady()) {
                     conn.produceOutput(this.handler);
                 }
-                sslSession.outboudTransport();
+                sslSession.outboundTransport();
             }
         } catch (IOException ex) {
             this.handler.exception(conn, ex);

Modified: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLIOSession.java Tue Feb 13 09:53:26 2007
@@ -237,7 +237,7 @@
         updateEventMask();
     }
     
-    public synchronized void outboudTransport() throws IOException {
+    public synchronized void outboundTransport() throws IOException {
         sendEncryptedData();
         doHandshake();
         updateEventMask();

Modified: jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java?view=diff&rev=507119&r1=507118&r2=507119
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-niossl/src/main/java/org/apache/http/impl/nio/reactor/SSLServerIOEventDispatch.java Tue Feb 13 09:53:26 2007
@@ -129,7 +129,7 @@
                 if (sslSession.isAppOutputReady()) {
                     conn.produceOutput(this.handler);
                 }
-                sslSession.outboudTransport();
+                sslSession.outboundTransport();
             }
         } catch (IOException ex) {
             this.handler.exception(conn, ex);