View Javadoc

    1   /*
    2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/ExpectContinueMethod.java,v 1.13 2004/05/08 10:12:08 olegk Exp $
    3    * $Revision: 480424 $
    4    * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
    5    *
    6    * ====================================================================
    7    *
    8    *  Licensed to the Apache Software Foundation (ASF) under one or more
    9    *  contributor license agreements.  See the NOTICE file distributed with
    10   *  this work for additional information regarding copyright ownership.
    11   *  The ASF licenses this file to You under the Apache License, Version 2.0
    12   *  (the "License"); you may not use this file except in compliance with
    13   *  the License.  You may obtain a copy of the License at
    14   *
    15   *      http://www.apache.org/licenses/LICENSE-2.0
    16   *
    17   *  Unless required by applicable law or agreed to in writing, software
    18   *  distributed under the License is distributed on an "AS IS" BASIS,
    19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    20   *  See the License for the specific language governing permissions and
    21   *  limitations under the License.
    22   * ====================================================================
    23   *
    24   * This software consists of voluntary contributions made by many
    25   * individuals on behalf of the Apache Software Foundation.  For more
    26   * information on the Apache Software Foundation, please see
    27   * <http://www.apache.org/>.
    28   *
    29   */
    30
    31  package org.apache.commons.httpclient.methods;
    32
    33  import java.io.IOException;
    34  import org.apache.commons.httpclient.HttpConnection;
    35  import org.apache.commons.httpclient.HttpException;
    36  import org.apache.commons.httpclient.HttpMethodBase;
    37  import org.apache.commons.httpclient.HttpState;
    38  import org.apache.commons.httpclient.HttpVersion;
    39  import org.apache.commons.httpclient.params.HttpMethodParams;
    40  import org.apache.commons.logging.Log;
    41  import org.apache.commons.logging.LogFactory;
    42
    43  /**
    44   * <p>
    45   * This abstract class serves as a foundation for all HTTP methods
    46   * that support 'Expect: 100-continue' handshake.
    47   * </p>
    48   *
    49   * <p>
    50   * The purpose of the 100 (Continue) status (refer to section 10.1.1
    51   * of the RFC 2616 for more details) is to allow a client that is
    52   * sending a request message with a request body to determine if the
    53   * origin server is willing to accept the request (based on the request
    54   * headers) before the client sends the request body. In some cases,
    55   * it might either be inappropriate or highly inefficient for the
    56   * client to send the body if the server will reject the message
    57   * without looking at the body.
    58   * </p>
    59   *
    60   * <p>
    61   * 'Expect: 100-continue' handshake should be used with caution,
    62   * as it may cause problems with HTTP servers and proxies that
    63   * do not support HTTP/1.1 protocol.
    64   * </p>
    65   *
    66   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
    67   *
    68   * @since 2.0beta1
    69   */
    70
    71  public abstract class ExpectContinueMethod extends HttpMethodBase {
    72
    73      /** LOG object for this class. */
    74      private static final Log LOG = LogFactory.getLog(ExpectContinueMethod.class);
    75
    76      /**
    77       * No-arg constructor.
    78       *
    79       * @since 2.0
    80       */
    81      public ExpectContinueMethod() {
    82          super();
    83      }
    84
    85      /**
    86       * Constructor specifying a URI.
    87       *
    88       * @param uri either an absolute or relative URI
    89       *
    90       * @since 2.0
    91       */
    92      public ExpectContinueMethod(String uri) {
    93          super(uri);
    94      }
    95
    96      /**
    97       * <p>
    98       * Returns <tt>true</tt> if the 'Expect: 100-Continue' handshake
    99       * is activated. The purpose of the 'Expect: 100-Continue'
    100      * handshake to allow a client that is sending a request message
    101      * with a request body to determine if the origin server is
    102      * willing to accept the request (based on the request headers)
    103      * before the client sends the request body.
    104      * </p>
    105      *
    106      * @return <tt>true</tt> if 'Expect: 100-Continue' handshake is to
    107      * be used, <tt>false</tt> otherwise.
    108      *
    109      * @since 2.0beta1
    110      *
    111      * @deprecated Use {@link HttpMethodParams}
    112      *
    113      * @see #getParams()
    114      * @see HttpMethodParams
    115      * @see HttpMethodParams#USE_EXPECT_CONTINUE
    116      */
    117     public boolean getUseExpectHeader() {
    118         return getParams().getBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false);
    119     }
    120
    121     /**
    122      * <p>
    123      * Activates 'Expect: 100-Continue' handshake. The purpose of
    124      * the 'Expect: 100-Continue' handshake to allow a client that is
    125      * sending a request message with a request body to determine if
    126      * the origin server is willing to accept the request (based on
    127      * the request headers) before the client sends the request body.
    128      * </p>
    129      *
    130      * <p>
    131      * The use of the 'Expect: 100-continue' handshake can result in
    132      * noticable peformance improvement for entity enclosing requests
    133      * (such as POST and PUT) that require the target server's
    134      * authentication.
    135      * </p>
    136      *
    137      * <p>
    138      * 'Expect: 100-continue' handshake should be used with
    139      * caution, as it may cause problems with HTTP servers and
    140      * proxies that do not support HTTP/1.1 protocol.
    141      * </p>
    142      *
    143      * @param value boolean value
    144      *
    145      * @since 2.0beta1
    146      *
    147      * @deprecated Use {@link HttpMethodParams}
    148      *
    149      * @see #getParams()
    150      * @see HttpMethodParams
    151      * @see HttpMethodParams#USE_EXPECT_CONTINUE
    152      */
    153     public void setUseExpectHeader(boolean value) {
    154         getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, value);
    155     }
    156
    157     /**
    158      * Returns <tt>true</tt> if there is a request body to be sent.
    159      * 'Expect: 100-continue' handshake may not be used if request
    160      * body is not present
    161      *
    162      * @return boolean
    163      *
    164      * @since 2.0beta1
    165      */
    166     protected abstract boolean hasRequestContent();
    167
    168     /**
    169      * Sets the <tt>Expect</tt> header if it has not already been set,
    170      * in addition to the "standard" set of headers.
    171      *
    172      * @param state the {@link HttpState state} information associated with this method
    173      * @param conn the {@link HttpConnection connection} used to execute
    174      *        this HTTP method
    175      *
    176      * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
    177      *                     can be recovered from.
    178      * @throws HttpException  if a protocol exception occurs. Usually protocol exceptions
    179      *                    cannot be recovered from.
    180      */
    181     protected void addRequestHeaders(HttpState state, HttpConnection conn)
    182     throws IOException, HttpException {
    183         LOG.trace("enter ExpectContinueMethod.addRequestHeaders(HttpState, HttpConnection)");
    184
    185         super.addRequestHeaders(state, conn);
    186         // If the request is being retried, the header may already be present
    187         boolean headerPresent = (getRequestHeader("Expect") != null);
    188         // See if the expect header should be sent
    189         // = HTTP/1.1 or higher
    190         // = request body present
    191
    192         if (getParams().isParameterTrue(HttpMethodParams.USE_EXPECT_CONTINUE)
    193         && getEffectiveVersion().greaterEquals(HttpVersion.HTTP_1_1)
    194         && hasRequestContent())
    195         {
    196             if (!headerPresent) {
    197                 setRequestHeader("Expect", "100-continue");
    198             }
    199         } else {
    200             if (headerPresent) {
    201                 removeRequestHeader("Expect");
    202             }
    203         }
    204     }
    205 }