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