Showing the changes to java/pkg/java/net/HttpURLConnection.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,804 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package java.net; | ||
| 27 | |||
| 28 | import java.io.InputStream; | ||
| 29 | import java.io.IOException; | ||
| 30 | import java.security.Permission; | ||
| 31 | import java.util.Date; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * A URLConnection with support for HTTP-specific features. See | ||
| 35 | * <A HREF="http://www.w3.org/pub/WWW/Protocols/"> the spec </A> for | ||
| 36 | * details. | ||
| 37 | * <p> | ||
| 38 | * | ||
| 39 | * Each HttpURLConnection instance is used to make a single request | ||
| 40 | * but the underlying network connection to the HTTP server may be | ||
| 41 | * transparently shared by other instances. Calling the close() methods | ||
| 42 | * on the InputStream or OutputStream of an HttpURLConnection | ||
| 43 | * after a request may free network resources associated with this | ||
| 44 | * instance but has no effect on any shared persistent connection. | ||
| 45 | * Calling the disconnect() method may close the underlying socket | ||
| 46 | * if a persistent connection is otherwise idle at that time. | ||
| 47 | * | ||
| 48 | * <P>The HTTP protocol handler has a few settings that can be accessed through | ||
| 49 | * System Properties. This covers | ||
| 50 | * <a href="doc-files/net-properties.html#Proxies">Proxy settings</a> as well as | ||
| 51 | * <a href="doc-files/net-properties.html#MiscHTTP"> various other settings</a>. | ||
| 52 | * </P> | ||
| 53 | * | ||
| 54 | * @see java.net.HttpURLConnection#disconnect() | ||
| 55 | * @since JDK1.1 | ||
| 56 | */ | ||
| 57 | abstract public class HttpURLConnection extends URLConnection { | ||
| 58 | /* instance variables */ | ||
| 59 | |||
| 60 | /** | ||
| 61 | * The HTTP method (GET,POST,PUT,etc.). | ||
| 62 | */ | ||
| 63 | protected String method = "GET"; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * The chunk-length when using chunked encoding streaming mode for output. | ||
| 67 | * A value of <code>-1</code> means chunked encoding is disabled for output. | ||
| 68 | * @since 1.5 | ||
| 69 | */ | ||
| 70 | protected int chunkLength = -1; | ||
| 71 | |||
| 72 | /** | ||
| 73 | * The fixed content-length when using fixed-length streaming mode. | ||
| 74 | * A value of <code>-1</code> means fixed-length streaming mode is disabled | ||
| 75 | * for output. | ||
| 76 | * | ||
| 77 | * <P> <B>NOTE:</B> {@link #fixedContentLengthLong} is recommended instead | ||
| 78 | * of this field, as it allows larger content lengths to be set. | ||
| 79 | * | ||
| 80 | * @since 1.5 | ||
| 81 | */ | ||
| 82 | protected int fixedContentLength = -1; | ||
| 83 | |||
| 84 | /** | ||
| 85 | * The fixed content-length when using fixed-length streaming mode. | ||
| 86 | * A value of {@code -1} means fixed-length streaming mode is disabled | ||
| 87 | * for output. | ||
| 88 | * | ||
| 89 | * @since 1.7 | ||
| 90 | */ | ||
| 91 | protected long fixedContentLengthLong = -1; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * Returns the key for the <code>n</code><sup>th</sup> header field. | ||
| 95 | * Some implementations may treat the <code>0</code><sup>th</sup> | ||
| 96 | * header field as special, i.e. as the status line returned by the HTTP | ||
| 97 | * server. In this case, {@link #getHeaderField(int) getHeaderField(0)} returns the status | ||
| 98 | * line, but <code>getHeaderFieldKey(0)</code> returns null. | ||
| 99 | * | ||
| 100 | * @param n an index, where n >=0. | ||
| 101 | * @return the key for the <code>n</code><sup>th</sup> header field, | ||
| 102 | * or <code>null</code> if the key does not exist. | ||
| 103 | */ | ||
| 104 | public String getHeaderFieldKey (int n) { | ||
| 105 | return null; | ||
| 106 | } | ||
| 107 | |||
| 108 | /** | ||
| 109 | * This method is used to enable streaming of a HTTP request body | ||
| 110 | * without internal buffering, when the content length is known in | ||
| 111 | * advance. | ||
| 112 | * <p> | ||
| 113 | * An exception will be thrown if the application | ||
| 114 | * attempts to write more data than the indicated | ||
| 115 | * content-length, or if the application closes the OutputStream | ||
| 116 | * before writing the indicated amount. | ||
| 117 | * <p> | ||
| 118 | * When output streaming is enabled, authentication | ||
| 119 | * and redirection cannot be handled automatically. | ||
| 120 | * A HttpRetryException will be thrown when reading | ||
| 121 | * the response if authentication or redirection are required. | ||
| 122 | * This exception can be queried for the details of the error. | ||
| 123 | * <p> | ||
| 124 | * This method must be called before the URLConnection is connected. | ||
| 125 | * <p> | ||
| 126 | * <B>NOTE:</B> {@link #setFixedLengthStreamingMode(long)} is recommended | ||
| 127 | * instead of this method as it allows larger content lengths to be set. | ||
| 128 | * | ||
| 129 | * @param contentLength The number of bytes which will be written | ||
| 130 | * to the OutputStream. | ||
| 131 | * | ||
| 132 | * @throws IllegalStateException if URLConnection is already connected | ||
| 133 | * or if a different streaming mode is already enabled. | ||
| 134 | * | ||
| 135 | * @throws IllegalArgumentException if a content length less than | ||
| 136 | * zero is specified. | ||
| 137 | * | ||
| 138 | * @see #setChunkedStreamingMode(int) | ||
| 139 | * @since 1.5 | ||
| 140 | */ | ||
| 141 | public void setFixedLengthStreamingMode (int contentLength) { | ||
| 142 | if (connected) { | ||
| 143 | throw new IllegalStateException ("Already connected"); | ||
| 144 | } | ||
| 145 | if (chunkLength != -1) { | ||
| 146 | throw new IllegalStateException ("Chunked encoding streaming mode set"); | ||
| 147 | } | ||
| 148 | if (contentLength < 0) { | ||
| 149 | throw new IllegalArgumentException ("invalid content length"); | ||
| 150 | } | ||
| 151 | fixedContentLength = contentLength; | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * This method is used to enable streaming of a HTTP request body | ||
| 156 | * without internal buffering, when the content length is known in | ||
| 157 | * advance. | ||
| 158 | * | ||
| 159 | * <P> An exception will be thrown if the application attempts to write | ||
| 160 | * more data than the indicated content-length, or if the application | ||
| 161 | * closes the OutputStream before writing the indicated amount. | ||
| 162 | * | ||
| 163 | * <P> When output streaming is enabled, authentication and redirection | ||
| 164 | * cannot be handled automatically. A {@linkplain HttpRetryException} will | ||
| 165 | * be thrown when reading the response if authentication or redirection | ||
| 166 | * are required. This exception can be queried for the details of the | ||
| 167 | * error. | ||
| 168 | * | ||
| 169 | * <P> This method must be called before the URLConnection is connected. | ||
| 170 | * | ||
| 171 | * <P> The content length set by invoking this method takes precedence | ||
| 172 | * over any value set by {@link #setFixedLengthStreamingMode(int)}. | ||
| 173 | * | ||
| 174 | * @param contentLength | ||
| 175 | * The number of bytes which will be written to the OutputStream. | ||
| 176 | * | ||
| 177 | * @throws IllegalStateException | ||
| 178 | * if URLConnection is already connected or if a different | ||
| 179 | * streaming mode is already enabled. | ||
| 180 | * | ||
| 181 | * @throws IllegalArgumentException | ||
| 182 | * if a content length less than zero is specified. | ||
| 183 | * | ||
| 184 | * @since 1.7 | ||
| 185 | */ | ||
| 186 | public void setFixedLengthStreamingMode(long contentLength) { | ||
| 187 | if (connected) { | ||
| 188 | throw new IllegalStateException("Already connected"); | ||
| 189 | } | ||
| 190 | if (chunkLength != -1) { | ||
| 191 | throw new IllegalStateException( | ||
| 192 | "Chunked encoding streaming mode set"); | ||
| 193 | } | ||
| 194 | if (contentLength < 0) { | ||
| 195 | throw new IllegalArgumentException("invalid content length"); | ||
| 196 | } | ||
| 197 | fixedContentLengthLong = contentLength; | ||
| 198 | } | ||
| 199 | |||
| 200 | /* Default chunk size (including chunk header) if not specified; | ||
| 201 | * we want to keep this in sync with the one defined in | ||
| 202 | * sun.net.www.http.ChunkedOutputStream | ||
| 203 | */ | ||
| 204 | private static final int DEFAULT_CHUNK_SIZE = 4096; | ||
| 205 | |||
| 206 | /** | ||
| 207 | * This method is used to enable streaming of a HTTP request body | ||
| 208 | * without internal buffering, when the content length is <b>not</b> | ||
| 209 | * known in advance. In this mode, chunked transfer encoding | ||
| 210 | * is used to send the request body. Note, not all HTTP servers | ||
| 211 | * support this mode. | ||
| 212 | * <p> | ||
| 213 | * When output streaming is enabled, authentication | ||
| 214 | * and redirection cannot be handled automatically. | ||
| 215 | * A HttpRetryException will be thrown when reading | ||
| 216 | * the response if authentication or redirection are required. | ||
| 217 | * This exception can be queried for the details of the error. | ||
| 218 | * <p> | ||
| 219 | * This method must be called before the URLConnection is connected. | ||
| 220 | * | ||
| 221 | * @param chunklen The number of bytes to write in each chunk. | ||
| 222 | * If chunklen is less than or equal to zero, a default | ||
| 223 | * value will be used. | ||
| 224 | * | ||
| 225 | * @throws IllegalStateException if URLConnection is already connected | ||
| 226 | * or if a different streaming mode is already enabled. | ||
| 227 | * | ||
| 228 | * @see #setFixedLengthStreamingMode(int) | ||
| 229 | * @since 1.5 | ||
| 230 | */ | ||
| 231 | public void setChunkedStreamingMode (int chunklen) { | ||
| 232 | if (connected) { | ||
| 233 | throw new IllegalStateException ("Can't set streaming mode: already connected"); | ||
| 234 | } | ||
| 235 | if (fixedContentLength != -1 || fixedContentLengthLong != -1) { | ||
| 236 | throw new IllegalStateException ("Fixed length streaming mode set"); | ||
| 237 | } | ||
| 238 | chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen; | ||
| 239 | } | ||
| 240 | |||
| 241 | /** | ||
| 242 | * Returns the value for the <code>n</code><sup>th</sup> header field. | ||
| 243 | * Some implementations may treat the <code>0</code><sup>th</sup> | ||
| 244 | * header field as special, i.e. as the status line returned by the HTTP | ||
| 245 | * server. | ||
| 246 | * <p> | ||
| 247 | * This method can be used in conjunction with the | ||
| 248 | * {@link #getHeaderFieldKey getHeaderFieldKey} method to iterate through all | ||
| 249 | * the headers in the message. | ||
| 250 | * | ||
| 251 | * @param n an index, where n>=0. | ||
| 252 | * @return the value of the <code>n</code><sup>th</sup> header field, | ||
| 253 | * or <code>null</code> if the value does not exist. | ||
| 254 | * @see java.net.HttpURLConnection#getHeaderFieldKey(int) | ||
| 255 | */ | ||
| 256 | public String getHeaderField(int n) { | ||
| 257 | return null; | ||
| 258 | } | ||
| 259 | |||
| 260 | /** | ||
| 261 | * An <code>int</code> representing the three digit HTTP Status-Code. | ||
| 262 | * <ul> | ||
| 263 | * <li> 1xx: Informational | ||
| 264 | * <li> 2xx: Success | ||
| 265 | * <li> 3xx: Redirection | ||
| 266 | * <li> 4xx: Client Error | ||
| 267 | * <li> 5xx: Server Error | ||
| 268 | * </ul> | ||
| 269 | */ | ||
| 270 | protected int responseCode = -1; | ||
| 271 | |||
| 272 | /** | ||
| 273 | * The HTTP response message. | ||
| 274 | */ | ||
| 275 | protected String responseMessage = null; | ||
| 276 | |||
| 277 | /* static variables */ | ||
| 278 | |||
| 279 | /* do we automatically follow redirects? The default is true. */ | ||
| 280 | private static boolean followRedirects = true; | ||
| 281 | |||
| 282 | /** | ||
| 283 | * If <code>true</code>, the protocol will automatically follow redirects. | ||
| 284 | * If <code>false</code>, the protocol will not automatically follow | ||
| 285 | * redirects. | ||
| 286 | * <p> | ||
| 287 | * This field is set by the <code>setInstanceFollowRedirects</code> | ||
| 288 | * method. Its value is returned by the <code>getInstanceFollowRedirects</code> | ||
| 289 | * method. | ||
| 290 | * <p> | ||
| 291 | * Its default value is based on the value of the static followRedirects | ||
| 292 | * at HttpURLConnection construction time. | ||
| 293 | * | ||
| 294 | * @see java.net.HttpURLConnection#setInstanceFollowRedirects(boolean) | ||
| 295 | * @see java.net.HttpURLConnection#getInstanceFollowRedirects() | ||
| 296 | * @see java.net.HttpURLConnection#setFollowRedirects(boolean) | ||
| 297 | */ | ||
| 298 | protected boolean instanceFollowRedirects = followRedirects; | ||
| 299 | |||
| 300 | /* valid HTTP methods */ | ||
| 301 | private static final String[] methods = { | ||
| 302 | "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE" | ||
| 303 | }; | ||
| 304 | |||
| 305 | /** | ||
| 306 | * Constructor for the HttpURLConnection. | ||
| 307 | * @param u the URL | ||
| 308 | */ | ||
| 309 | protected HttpURLConnection (URL u) { | ||
| 310 | super(u); | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * Sets whether HTTP redirects (requests with response code 3xx) should | ||
| 315 | * be automatically followed by this class. True by default. Applets | ||
| 316 | * cannot change this variable. | ||
| 317 | * <p> | ||
| 318 | * If there is a security manager, this method first calls | ||
| 319 | * the security manager's <code>checkSetFactory</code> method | ||
| 320 | * to ensure the operation is allowed. | ||
| 321 | * This could result in a SecurityException. | ||
| 322 | * | ||
| 323 | * @param set a <code>boolean</code> indicating whether or not | ||
| 324 | * to follow HTTP redirects. | ||
| 325 | * @exception SecurityException if a security manager exists and its | ||
| 326 | * <code>checkSetFactory</code> method doesn't | ||
| 327 | * allow the operation. | ||
| 328 | * @see SecurityManager#checkSetFactory | ||
| 329 | * @see #getFollowRedirects() | ||
| 330 | */ | ||
| 331 | public static void setFollowRedirects(boolean set) { | ||
| 332 | SecurityManager sec = System.getSecurityManager(); | ||
| 333 | if (sec != null) { | ||
| 334 | // seems to be the best check here... | ||
| 335 | sec.checkSetFactory(); | ||
| 336 | } | ||
| 337 | followRedirects = set; | ||
| 338 | } | ||
| 339 | |||
| 340 | /** | ||
| 341 | * Returns a <code>boolean</code> indicating | ||
| 342 | * whether or not HTTP redirects (3xx) should | ||
| 343 | * be automatically followed. | ||
| 344 | * | ||
| 345 | * @return <code>true</code> if HTTP redirects should | ||
| 346 | * be automatically followed, <tt>false</tt> if not. | ||
| 347 | * @see #setFollowRedirects(boolean) | ||
| 348 | */ | ||
| 349 | public static boolean getFollowRedirects() { | ||
| 350 | return followRedirects; | ||
| 351 | } | ||
| 352 | |||
| 353 | /** | ||
| 354 | * Sets whether HTTP redirects (requests with response code 3xx) should | ||
| 355 | * be automatically followed by this <code>HttpURLConnection</code> | ||
| 356 | * instance. | ||
| 357 | * <p> | ||
| 358 | * The default value comes from followRedirects, which defaults to | ||
| 359 | * true. | ||
| 360 | * | ||
| 361 | * @param followRedirects a <code>boolean</code> indicating | ||
| 362 | * whether or not to follow HTTP redirects. | ||
| 363 | * | ||
| 364 | * @see java.net.HttpURLConnection#instanceFollowRedirects | ||
| 365 | * @see #getInstanceFollowRedirects | ||
| 366 | * @since 1.3 | ||
| 367 | */ | ||
| 368 | public void setInstanceFollowRedirects(boolean followRedirects) { | ||
| 369 | instanceFollowRedirects = followRedirects; | ||
| 370 | } | ||
| 371 | |||
| 372 | /** | ||
| 373 | * Returns the value of this <code>HttpURLConnection</code>'s | ||
| 374 | * <code>instanceFollowRedirects</code> field. | ||
| 375 | * | ||
| 376 | * @return the value of this <code>HttpURLConnection</code>'s | ||
| 377 | * <code>instanceFollowRedirects</code> field. | ||
| 378 | * @see java.net.HttpURLConnection#instanceFollowRedirects | ||
| 379 | * @see #setInstanceFollowRedirects(boolean) | ||
| 380 | * @since 1.3 | ||
| 381 | */ | ||
| 382 | public boolean getInstanceFollowRedirects() { | ||
| 383 | return instanceFollowRedirects; | ||
| 384 | } | ||
| 385 | |||
| 386 | /** | ||
| 387 | * Set the method for the URL request, one of: | ||
| 388 | * <UL> | ||
| 389 | * <LI>GET | ||
| 390 | * <LI>POST | ||
| 391 | * <LI>HEAD | ||
| 392 | * <LI>OPTIONS | ||
| 393 | * <LI>PUT | ||
| 394 | * <LI>DELETE | ||
| 395 | * <LI>TRACE | ||
| 396 | * </UL> are legal, subject to protocol restrictions. The default | ||
| 397 | * method is GET. | ||
| 398 | * | ||
| 399 | * @param method the HTTP method | ||
| 400 | * @exception ProtocolException if the method cannot be reset or if | ||
| 401 | * the requested method isn't valid for HTTP. | ||
| 402 | * @exception SecurityException if a security manager is set and the | ||
| 403 | * method is "TRACE", but the "allowHttpTrace" | ||
| 404 | * NetPermission is not granted. | ||
| 405 | * @see #getRequestMethod() | ||
| 406 | */ | ||
| 407 | public void setRequestMethod(String method) throws ProtocolException { | ||
| 408 | if (connected) { | ||
| 409 | throw new ProtocolException("Can't reset method: already connected"); | ||
| 410 | } | ||
| 411 | // This restriction will prevent people from using this class to | ||
| 412 | // experiment w/ new HTTP methods using java. But it should | ||
| 413 | // be placed for security - the request String could be | ||
| 414 | // arbitrarily long. | ||
| 415 | |||
| 416 | for (int i = 0; i < methods.length; i++) { | ||
| 417 | if (methods[i].equals(method)) { | ||
| 418 | if (method.equals("TRACE")) { | ||
| 419 | SecurityManager s = System.getSecurityManager(); | ||
| 420 | if (s != null) { | ||
| 421 | s.checkPermission(new NetPermission("allowHttpTrace")); | ||
| 422 | } | ||
| 423 | } | ||
| 424 | this.method = method; | ||
| 425 | return; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | throw new ProtocolException("Invalid HTTP method: " + method); | ||
| 429 | } | ||
| 430 | |||
| 431 | /** | ||
| 432 | * Get the request method. | ||
| 433 | * @return the HTTP request method | ||
| 434 | * @see #setRequestMethod(java.lang.String) | ||
| 435 | */ | ||
| 436 | public String getRequestMethod() { | ||
| 437 | return method; | ||
| 438 | } | ||
| 439 | |||
| 440 | /** | ||
| 441 | * Gets the status code from an HTTP response message. | ||
| 442 | * For example, in the case of the following status lines: | ||
| 443 | * <PRE> | ||
| 444 | * HTTP/1.0 200 OK | ||
| 445 | * HTTP/1.0 401 Unauthorized | ||
| 446 | * </PRE> | ||
| 447 | * It will return 200 and 401 respectively. | ||
| 448 | * Returns -1 if no code can be discerned | ||
| 449 | * from the response (i.e., the response is not valid HTTP). | ||
| 450 | * @throws IOException if an error occurred connecting to the server. | ||
| 451 | * @return the HTTP Status-Code, or -1 | ||
| 452 | */ | ||
| 453 | public int getResponseCode() throws IOException { | ||
| 454 | /* | ||
| 455 | * We're got the response code already | ||
| 456 | */ | ||
| 457 | if (responseCode != -1) { | ||
| 458 | return responseCode; | ||
| 459 | } | ||
| 460 | |||
| 461 | /* | ||
| 462 | * Ensure that we have connected to the server. Record | ||
| 463 | * exception as we need to re-throw it if there isn't | ||
| 464 | * a status line. | ||
| 465 | */ | ||
| 466 | Exception exc = null; | ||
| 467 | try { | ||
| 468 | getInputStream(); | ||
| 469 | } catch (Exception e) { | ||
| 470 | exc = e; | ||
| 471 | } | ||
| 472 | |||
| 473 | /* | ||
| 474 | * If we can't a status-line then re-throw any exception | ||
| 475 | * that getInputStream threw. | ||
| 476 | */ | ||
| 477 | String statusLine = getHeaderField(0); | ||
| 478 | if (statusLine == null) { | ||
| 479 | if (exc != null) { | ||
| 480 | if (exc instanceof RuntimeException) | ||
| 481 | throw (RuntimeException)exc; | ||
| 482 | else | ||
| 483 | throw (IOException)exc; | ||
| 484 | } | ||
| 485 | return -1; | ||
| 486 | } | ||
| 487 | |||
| 488 | /* | ||
| 489 | * Examine the status-line - should be formatted as per | ||
| 490 | * section 6.1 of RFC 2616 :- | ||
| 491 | * | ||
| 492 | * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase | ||
| 493 | * | ||
| 494 | * If status line can't be parsed return -1. | ||
| 495 | */ | ||
| 496 | if (statusLine.startsWith("HTTP/1.")) { | ||
| 497 | int codePos = statusLine.indexOf(' '); | ||
| 498 | if (codePos > 0) { | ||
| 499 | |||
| 500 | int phrasePos = statusLine.indexOf(' ', codePos+1); | ||
| 501 | if (phrasePos > 0 && phrasePos < statusLine.length()) { | ||
| 502 | responseMessage = statusLine.substring(phrasePos+1); | ||
| 503 | } | ||
| 504 | |||
| 505 | // deviation from RFC 2616 - don't reject status line | ||
| 506 | // if SP Reason-Phrase is not included. | ||
| 507 | if (phrasePos < 0) | ||
| 508 | phrasePos = statusLine.length(); | ||
| 509 | |||
| 510 | try { | ||
| 511 | responseCode = Integer.parseInt | ||
| 512 | (statusLine.substring(codePos+1, phrasePos)); | ||
| 513 | return responseCode; | ||
| 514 | } catch (NumberFormatException e) { } | ||
| 515 | } | ||
| 516 | } | ||
| 517 | return -1; | ||
| 518 | } | ||
| 519 | |||
| 520 | /** | ||
| 521 | * Gets the HTTP response message, if any, returned along with the | ||
| 522 | * response code from a server. From responses like: | ||
| 523 | * <PRE> | ||
| 524 | * HTTP/1.0 200 OK | ||
| 525 | * HTTP/1.0 404 Not Found | ||
| 526 | * </PRE> | ||
| 527 | * Extracts the Strings "OK" and "Not Found" respectively. | ||
| 528 | * Returns null if none could be discerned from the responses | ||
| 529 | * (the result was not valid HTTP). | ||
| 530 | * @throws IOException if an error occurred connecting to the server. | ||
| 531 | * @return the HTTP response message, or <code>null</code> | ||
| 532 | */ | ||
| 533 | public String getResponseMessage() throws IOException { | ||
| 534 | getResponseCode(); | ||
| 535 | return responseMessage; | ||
| 536 | } | ||
| 537 | |||
| 538 | public long getHeaderFieldDate(String name, long Default) { | ||
| 539 | String dateString = getHeaderField(name); | ||
| 540 | try { | ||
| 541 | if (dateString.indexOf("GMT") == -1) { | ||
| 542 | dateString = dateString+" GMT"; | ||
| 543 | } | ||
| 544 | return Date.parse(dateString); | ||
| 545 | } catch (Exception e) { | ||
| 546 | } | ||
| 547 | return Default; | ||
| 548 | } | ||
| 549 | |||
| 550 | |||
| 551 | /** | ||
| 552 | * Indicates that other requests to the server | ||
| 553 | * are unlikely in the near future. Calling disconnect() | ||
| 554 | * should not imply that this HttpURLConnection | ||
| 555 | * instance can be reused for other requests. | ||
| 556 | */ | ||
| 557 | public abstract void disconnect(); | ||
| 558 | |||
| 559 | /** | ||
| 560 | * Indicates if the connection is going through a proxy. | ||
| 561 | * @return a boolean indicating if the connection is | ||
| 562 | * using a proxy. | ||
| 563 | */ | ||
| 564 | public abstract boolean usingProxy(); | ||
| 565 | |||
| 566 | /** | ||
| 567 | * Returns a {@link SocketPermission} object representing the | ||
| 568 | * permission necessary to connect to the destination host and port. | ||
| 569 | * | ||
| 570 | * @exception IOException if an error occurs while computing | ||
| 571 | * the permission. | ||
| 572 | * | ||
| 573 | * @return a <code>SocketPermission</code> object representing the | ||
| 574 | * permission necessary to connect to the destination | ||
| 575 | * host and port. | ||
| 576 | */ | ||
| 577 | public Permission getPermission() throws IOException { | ||
| 578 | int port = url.getPort(); | ||
| 579 | port = port < 0 ? 80 : port; | ||
| 580 | String host = url.getHost() + ":" + port; | ||
| 581 | Permission permission = new SocketPermission(host, "connect"); | ||
| 582 | return permission; | ||
| 583 | } | ||
| 584 | |||
| 585 | /** | ||
| 586 | * Returns the error stream if the connection failed | ||
| 587 | * but the server sent useful data nonetheless. The | ||
| 588 | * typical example is when an HTTP server responds | ||
| 589 | * with a 404, which will cause a FileNotFoundException | ||
| 590 | * to be thrown in connect, but the server sent an HTML | ||
| 591 | * help page with suggestions as to what to do. | ||
| 592 | * | ||
| 593 | * <p>This method will not cause a connection to be initiated. If | ||
| 594 | * the connection was not connected, or if the server did not have | ||
| 595 | * an error while connecting or if the server had an error but | ||
| 596 | * no error data was sent, this method will return null. This is | ||
| 597 | * the default. | ||
| 598 | * | ||
| 599 | * @return an error stream if any, null if there have been no | ||
| 600 | * errors, the connection is not connected or the server sent no | ||
| 601 | * useful data. | ||
| 602 | */ | ||
| 603 | public InputStream getErrorStream() { | ||
| 604 | return null; | ||
| 605 | } | ||
| 606 | |||
| 607 | /** | ||
| 608 | * The response codes for HTTP, as of version 1.1. | ||
| 609 | */ | ||
| 610 | |||
| 611 | // REMIND: do we want all these?? | ||
| 612 | // Others not here that we do want?? | ||
| 613 | |||
| 614 | /* 2XX: generally "OK" */ | ||
| 615 | |||
| 616 | /** | ||
| 617 | * HTTP Status-Code 200: OK. | ||
| 618 | */ | ||
| 619 | public static final int HTTP_OK = 200; | ||
| 620 | |||
| 621 | /** | ||
| 622 | * HTTP Status-Code 201: Created. | ||
| 623 | */ | ||
| 624 | public static final int HTTP_CREATED = 201; | ||
| 625 | |||
| 626 | /** | ||
| 627 | * HTTP Status-Code 202: Accepted. | ||
| 628 | */ | ||
| 629 | public static final int HTTP_ACCEPTED = 202; | ||
| 630 | |||
| 631 | /** | ||
| 632 | * HTTP Status-Code 203: Non-Authoritative Information. | ||
| 633 | */ | ||
| 634 | public static final int HTTP_NOT_AUTHORITATIVE = 203; | ||
| 635 | |||
| 636 | /** | ||
| 637 | * HTTP Status-Code 204: No Content. | ||
| 638 | */ | ||
| 639 | public static final int HTTP_NO_CONTENT = 204; | ||
| 640 | |||
| 641 | /** | ||
| 642 | * HTTP Status-Code 205: Reset Content. | ||
| 643 | */ | ||
| 644 | public static final int HTTP_RESET = 205; | ||
| 645 | |||
| 646 | /** | ||
| 647 | * HTTP Status-Code 206: Partial Content. | ||
| 648 | */ | ||
| 649 | public static final int HTTP_PARTIAL = 206; | ||
| 650 | |||
| 651 | /* 3XX: relocation/redirect */ | ||
| 652 | |||
| 653 | /** | ||
| 654 | * HTTP Status-Code 300: Multiple Choices. | ||
| 655 | */ | ||
| 656 | public static final int HTTP_MULT_CHOICE = 300; | ||
| 657 | |||
| 658 | /** | ||
| 659 | * HTTP Status-Code 301: Moved Permanently. | ||
| 660 | */ | ||
| 661 | public static final int HTTP_MOVED_PERM = 301; | ||
| 662 | |||
| 663 | /** | ||
| 664 | * HTTP Status-Code 302: Temporary Redirect. | ||
| 665 | */ | ||
| 666 | public static final int HTTP_MOVED_TEMP = 302; | ||
| 667 | |||
| 668 | /** | ||
| 669 | * HTTP Status-Code 303: See Other. | ||
| 670 | */ | ||
| 671 | public static final int HTTP_SEE_OTHER = 303; | ||
| 672 | |||
| 673 | /** | ||
| 674 | * HTTP Status-Code 304: Not Modified. | ||
| 675 | */ | ||
| 676 | public static final int HTTP_NOT_MODIFIED = 304; | ||
| 677 | |||
| 678 | /** | ||
| 679 | * HTTP Status-Code 305: Use Proxy. | ||
| 680 | */ | ||
| 681 | public static final int HTTP_USE_PROXY = 305; | ||
| 682 | |||
| 683 | /* 4XX: client error */ | ||
| 684 | |||
| 685 | /** | ||
| 686 | * HTTP Status-Code 400: Bad Request. | ||
| 687 | */ | ||
| 688 | public static final int HTTP_BAD_REQUEST = 400; | ||
| 689 | |||
| 690 | /** | ||
| 691 | * HTTP Status-Code 401: Unauthorized. | ||
| 692 | */ | ||
| 693 | public static final int HTTP_UNAUTHORIZED = 401; | ||
| 694 | |||
| 695 | /** | ||
| 696 | * HTTP Status-Code 402: Payment Required. | ||
| 697 | */ | ||
| 698 | public static final int HTTP_PAYMENT_REQUIRED = 402; | ||
| 699 | |||
| 700 | /** | ||
| 701 | * HTTP Status-Code 403: Forbidden. | ||
| 702 | */ | ||
| 703 | public static final int HTTP_FORBIDDEN = 403; | ||
| 704 | |||
| 705 | /** | ||
| 706 | * HTTP Status-Code 404: Not Found. | ||
| 707 | */ | ||
| 708 | public static final int HTTP_NOT_FOUND = 404; | ||
| 709 | |||
| 710 | /** | ||
| 711 | * HTTP Status-Code 405: Method Not Allowed. | ||
| 712 | */ | ||
| 713 | public static final int HTTP_BAD_METHOD = 405; | ||
| 714 | |||
| 715 | /** | ||
| 716 | * HTTP Status-Code 406: Not Acceptable. | ||
| 717 | */ | ||
| 718 | public static final int HTTP_NOT_ACCEPTABLE = 406; | ||
| 719 | |||
| 720 | /** | ||
| 721 | * HTTP Status-Code 407: Proxy Authentication Required. | ||
| 722 | */ | ||
| 723 | public static final int HTTP_PROXY_AUTH = 407; | ||
| 724 | |||
| 725 | /** | ||
| 726 | * HTTP Status-Code 408: Request Time-Out. | ||
| 727 | */ | ||
| 728 | public static final int HTTP_CLIENT_TIMEOUT = 408; | ||
| 729 | |||
| 730 | /** | ||
| 731 | * HTTP Status-Code 409: Conflict. | ||
| 732 | */ | ||
| 733 | public static final int HTTP_CONFLICT = 409; | ||
| 734 | |||
| 735 | /** | ||
| 736 | * HTTP Status-Code 410: Gone. | ||
| 737 | */ | ||
| 738 | public static final int HTTP_GONE = 410; | ||
| 739 | |||
| 740 | /** | ||
| 741 | * HTTP Status-Code 411: Length Required. | ||
| 742 | */ | ||
| 743 | public static final int HTTP_LENGTH_REQUIRED = 411; | ||
| 744 | |||
| 745 | /** | ||
| 746 | * HTTP Status-Code 412: Precondition Failed. | ||
| 747 | */ | ||
| 748 | public static final int HTTP_PRECON_FAILED = 412; | ||
| 749 | |||
| 750 | /** | ||
| 751 | * HTTP Status-Code 413: Request Entity Too Large. | ||
| 752 | */ | ||
| 753 | public static final int HTTP_ENTITY_TOO_LARGE = 413; | ||
| 754 | |||
| 755 | /** | ||
| 756 | * HTTP Status-Code 414: Request-URI Too Large. | ||
| 757 | */ | ||
| 758 | public static final int HTTP_REQ_TOO_LONG = 414; | ||
| 759 | |||
| 760 | /** | ||
| 761 | * HTTP Status-Code 415: Unsupported Media Type. | ||
| 762 | */ | ||
| 763 | public static final int HTTP_UNSUPPORTED_TYPE = 415; | ||
| 764 | |||
| 765 | /* 5XX: server error */ | ||
| 766 | |||
| 767 | /** | ||
| 768 | * HTTP Status-Code 500: Internal Server Error. | ||
| 769 | * @deprecated it is misplaced and shouldn't have existed. | ||
| 770 | */ | ||
| 771 | @Deprecated | ||
| 772 | public static final int HTTP_SERVER_ERROR = 500; | ||
| 773 | |||
| 774 | /** | ||
| 775 | * HTTP Status-Code 500: Internal Server Error. | ||
| 776 | */ | ||
| 777 | public static final int HTTP_INTERNAL_ERROR = 500; | ||
| 778 | |||
| 779 | /** | ||
| 780 | * HTTP Status-Code 501: Not Implemented. | ||
| 781 | */ | ||
| 782 | public static final int HTTP_NOT_IMPLEMENTED = 501; | ||
| 783 | |||
| 784 | /** | ||
| 785 | * HTTP Status-Code 502: Bad Gateway. | ||
| 786 | */ | ||
| 787 | public static final int HTTP_BAD_GATEWAY = 502; | ||
| 788 | |||
| 789 | /** | ||
| 790 | * HTTP Status-Code 503: Service Unavailable. | ||
| 791 | */ | ||
| 792 | public static final int HTTP_UNAVAILABLE = 503; | ||
| 793 | |||
| 794 | /** | ||
| 795 | * HTTP Status-Code 504: Gateway Timeout. | ||
| 796 | */ | ||
| 797 | public static final int HTTP_GATEWAY_TIMEOUT = 504; | ||
| 798 | |||
| 799 | /** | ||
| 800 | * HTTP Status-Code 505: HTTP Version Not Supported. | ||
| 801 | */ | ||
| 802 | public static final int HTTP_VERSION = 505; | ||
| 803 | |||
| 804 | } | ||