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