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
35 import org.apache.commons.httpclient.HttpConnection;
36 import org.apache.commons.httpclient.HttpException;
37 import org.apache.commons.httpclient.HttpMethodBase;
38 import org.apache.commons.httpclient.HttpState;
39 import org.apache.commons.httpclient.ProtocolException;
40 import org.apache.commons.httpclient.params.HttpMethodParams;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44 /***
45 * Implements the HTTP HEAD method.
46 * <p>
47 * The HTTP HEAD method is defined in section 9.4 of
48 * <a href="http://www.ietf.org/rfc/rfc2616.txt">RFC2616</a>:
49 * <blockquote>
50 * The HEAD method is identical to GET except that the server MUST NOT
51 * return a message-body in the response. The metainformation contained
52 * in the HTTP headers in response to a HEAD request SHOULD be identical
53 * to the information sent in response to a GET request. This method can
54 * be used for obtaining metainformation about the entity implied by the
55 * request without transferring the entity-body itself. This method is
56 * often used for testing hypertext links for validity, accessibility,
57 * and recent modification.
58 * </blockquote>
59 * </p>
60 *
61 * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
62 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
63 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
64 * @author <a href="mailto:oleg@ural.ru">oleg Kalnichevski</a>
65 *
66 * @version $Revision$
67 * @since 1.0
68 */
69 public class HeadMethod extends HttpMethodBase {
70
71
72 /*** Log object for this class. */
73 private static final Log LOG = LogFactory.getLog(HeadMethod.class);
74
75
76
77 /***
78 * No-arg constructor.
79 *
80 * @since 1.0
81 */
82 public HeadMethod() {
83 setFollowRedirects(true);
84 }
85
86 /***
87 * Constructor specifying a URI.
88 *
89 * @param uri either an absolute or relative URI
90 *
91 * @since 1.0
92 */
93 public HeadMethod(String uri) {
94 super(uri);
95 setFollowRedirects(true);
96 }
97
98
99
100 /***
101 * Returns <tt>"HEAD"</tt>.
102 *
103 * @return <tt>"HEAD"</tt>
104 *
105 * @since 2.0
106 */
107 public String getName() {
108 return "HEAD";
109 }
110
111 /***
112 * Recycles the HTTP method so that it can be used again.
113 * Note that all of the instance variables will be reset
114 * once this method has been called. This method will also
115 * release the connection being used by this HTTP method.
116 *
117 * @see #releaseConnection()
118 *
119 * @since 1.0
120 *
121 * @deprecated no longer supported and will be removed in the future
122 * version of HttpClient
123 */
124 public void recycle() {
125 super.recycle();
126 setFollowRedirects(true);
127 }
128
129 /***
130 * Overrides {@link HttpMethodBase} method to <i>not</i> read a response
131 * body, despite the presence of a <tt>Content-Length</tt> or
132 * <tt>Transfer-Encoding</tt> header.
133 *
134 * @param state the {@link HttpState state} information associated with this method
135 * @param conn the {@link HttpConnection connection} used to execute
136 * this HTTP method
137 *
138 * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
139 * can be recovered from.
140 * @throws HttpException if a protocol exception occurs. Usually protocol exceptions
141 * cannot be recovered from.
142 *
143 * @see #readResponse
144 * @see #processResponseBody
145 *
146 * @since 2.0
147 */
148 protected void readResponseBody(HttpState state, HttpConnection conn)
149 throws HttpException, IOException {
150 LOG.trace(
151 "enter HeadMethod.readResponseBody(HttpState, HttpConnection)");
152
153 int bodyCheckTimeout =
154 getParams().getIntParameter(HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, -1);
155
156 if (bodyCheckTimeout < 0) {
157 responseBodyConsumed();
158 } else {
159 if (LOG.isDebugEnabled()) {
160 LOG.debug("Check for non-compliant response body. Timeout in "
161 + bodyCheckTimeout + " ms");
162 }
163 boolean responseAvailable = false;
164 try {
165 responseAvailable = conn.isResponseAvailable(bodyCheckTimeout);
166 } catch (IOException e) {
167 LOG.debug("An IOException occurred while testing if a response was available,"
168 + " we will assume one is not.",
169 e);
170 responseAvailable = false;
171 }
172 if (responseAvailable) {
173 if (getParams().isParameterTrue(HttpMethodParams.REJECT_HEAD_BODY)) {
174 throw new ProtocolException(
175 "Body content may not be sent in response to HTTP HEAD request");
176 } else {
177 LOG.warn("Body content returned in response to HTTP HEAD");
178 }
179 super.readResponseBody(state, conn);
180 }
181 }
182
183 }
184
185 /***
186 * Returns non-compliant response body check timeout.
187 *
188 * @return The period of time in milliseconds to wait for a response
189 * body from a non-compliant server. <tt>-1</tt> returned when
190 * non-compliant response body check is disabled
191 *
192 * @deprecated Use {@link HttpMethodParams}
193 *
194 * @see #getParams()
195 * @see HttpMethodParams
196 * @see HttpMethodParams#HEAD_BODY_CHECK_TIMEOUT
197 */
198 public int getBodyCheckTimeout() {
199 return getParams().getIntParameter(HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, -1);
200 }
201
202 /***
203 * Sets non-compliant response body check timeout.
204 *
205 * @param timeout The period of time in milliseconds to wait for a response
206 * body from a non-compliant server. <tt>-1</tt> can be used to
207 * disable non-compliant response body check
208 *
209 * @deprecated Use {@link HttpMethodParams}
210 *
211 * @see #getParams()
212 * @see HttpMethodParams
213 * @see HttpMethodParams#HEAD_BODY_CHECK_TIMEOUT
214 */
215 public void setBodyCheckTimeout(int timeout) {
216 getParams().setIntParameter(HttpMethodParams.HEAD_BODY_CHECK_TIMEOUT, timeout);
217 }
218
219 }