1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
187 boolean headerPresent = (getRequestHeader("Expect") != null);
188
189
190
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 }