001: /*
002: * $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 $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient.methods;
032:
033: import java.io.IOException;
034: import org.apache.commons.httpclient.HttpConnection;
035: import org.apache.commons.httpclient.HttpException;
036: import org.apache.commons.httpclient.HttpMethodBase;
037: import org.apache.commons.httpclient.HttpState;
038: import org.apache.commons.httpclient.HttpVersion;
039: import org.apache.commons.httpclient.params.HttpMethodParams;
040: import org.apache.commons.logging.Log;
041: import org.apache.commons.logging.LogFactory;
042:
043: /**
044: * <p>
045: * This abstract class serves as a foundation for all HTTP methods
046: * that support 'Expect: 100-continue' handshake.
047: * </p>
048: *
049: * <p>
050: * The purpose of the 100 (Continue) status (refer to section 10.1.1
051: * of the RFC 2616 for more details) is to allow a client that is
052: * sending a request message with a request body to determine if the
053: * origin server is willing to accept the request (based on the request
054: * headers) before the client sends the request body. In some cases,
055: * it might either be inappropriate or highly inefficient for the
056: * client to send the body if the server will reject the message
057: * without looking at the body.
058: * </p>
059: *
060: * <p>
061: * 'Expect: 100-continue' handshake should be used with caution,
062: * as it may cause problems with HTTP servers and proxies that
063: * do not support HTTP/1.1 protocol.
064: * </p>
065: *
066: * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
067: *
068: * @since 2.0beta1
069: */
070:
071: public abstract class ExpectContinueMethod extends HttpMethodBase {
072:
073: /** LOG object for this class. */
074: private static final Log LOG = LogFactory
075: .getLog(ExpectContinueMethod.class);
076:
077: /**
078: * No-arg constructor.
079: *
080: * @since 2.0
081: */
082: public ExpectContinueMethod() {
083: super ();
084: }
085:
086: /**
087: * Constructor specifying a URI.
088: *
089: * @param uri either an absolute or relative URI
090: *
091: * @since 2.0
092: */
093: public ExpectContinueMethod(String uri) {
094: super (uri);
095: }
096:
097: /**
098: * <p>
099: * Returns <tt>true</tt> if the 'Expect: 100-Continue' handshake
100: * is activated. The purpose of the 'Expect: 100-Continue'
101: * handshake to allow a client that is sending a request message
102: * with a request body to determine if the origin server is
103: * willing to accept the request (based on the request headers)
104: * before the client sends the request body.
105: * </p>
106: *
107: * @return <tt>true</tt> if 'Expect: 100-Continue' handshake is to
108: * be used, <tt>false</tt> otherwise.
109: *
110: * @since 2.0beta1
111: *
112: * @deprecated Use {@link HttpMethodParams}
113: *
114: * @see #getParams()
115: * @see HttpMethodParams
116: * @see HttpMethodParams#USE_EXPECT_CONTINUE
117: */
118: public boolean getUseExpectHeader() {
119: return getParams().getBooleanParameter(
120: HttpMethodParams.USE_EXPECT_CONTINUE, false);
121: }
122:
123: /**
124: * <p>
125: * Activates 'Expect: 100-Continue' handshake. The purpose of
126: * the 'Expect: 100-Continue' handshake to allow a client that is
127: * sending a request message with a request body to determine if
128: * the origin server is willing to accept the request (based on
129: * the request headers) before the client sends the request body.
130: * </p>
131: *
132: * <p>
133: * The use of the 'Expect: 100-continue' handshake can result in
134: * noticable peformance improvement for entity enclosing requests
135: * (such as POST and PUT) that require the target server's
136: * authentication.
137: * </p>
138: *
139: * <p>
140: * 'Expect: 100-continue' handshake should be used with
141: * caution, as it may cause problems with HTTP servers and
142: * proxies that do not support HTTP/1.1 protocol.
143: * </p>
144: *
145: * @param value boolean value
146: *
147: * @since 2.0beta1
148: *
149: * @deprecated Use {@link HttpMethodParams}
150: *
151: * @see #getParams()
152: * @see HttpMethodParams
153: * @see HttpMethodParams#USE_EXPECT_CONTINUE
154: */
155: public void setUseExpectHeader(boolean value) {
156: getParams().setBooleanParameter(
157: HttpMethodParams.USE_EXPECT_CONTINUE, value);
158: }
159:
160: /**
161: * Returns <tt>true</tt> if there is a request body to be sent.
162: * 'Expect: 100-continue' handshake may not be used if request
163: * body is not present
164: *
165: * @return boolean
166: *
167: * @since 2.0beta1
168: */
169: protected abstract boolean hasRequestContent();
170:
171: /**
172: * Sets the <tt>Expect</tt> header if it has not already been set,
173: * in addition to the "standard" set of headers.
174: *
175: * @param state the {@link HttpState state} information associated with this method
176: * @param conn the {@link HttpConnection connection} used to execute
177: * this HTTP method
178: *
179: * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
180: * can be recovered from.
181: * @throws HttpException if a protocol exception occurs. Usually protocol exceptions
182: * cannot be recovered from.
183: */
184: protected void addRequestHeaders(HttpState state,
185: HttpConnection conn) throws IOException, HttpException {
186: LOG
187: .trace("enter ExpectContinueMethod.addRequestHeaders(HttpState, HttpConnection)");
188:
189: super .addRequestHeaders(state, conn);
190: // If the request is being retried, the header may already be present
191: boolean headerPresent = (getRequestHeader("Expect") != null);
192: // See if the expect header should be sent
193: // = HTTP/1.1 or higher
194: // = request body present
195:
196: if (getParams().isParameterTrue(
197: HttpMethodParams.USE_EXPECT_CONTINUE)
198: && getEffectiveVersion().greaterEquals(
199: HttpVersion.HTTP_1_1) && hasRequestContent()) {
200: if (!headerPresent) {
201: setRequestHeader("Expect", "100-continue");
202: }
203: } else {
204: if (headerPresent) {
205: removeRequestHeader("Expect");
206: }
207: }
208: }
209: }
|