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