1/*
2 * Copyright (c) 1996, 2016, 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
26package java.net;
27
28import java.io.InputStream;
29import java.io.IOException;
30import java.security.Permission;
31import 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 */
69public 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     * @exception  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     * @exception ProtocolException if the method cannot be reset or if
460     *              the requested method isn't valid for HTTP.
461     * @exception 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     * @return a boolean indicating if the connection is
622     * using a proxy.
623     */
624    public abstract boolean usingProxy();
625
626    /**
627     * Returns a {@link SocketPermission} object representing the
628     * permission necessary to connect to the destination host and port.
629     *
630     * @exception IOException if an error occurs while computing
631     *            the permission.
632     *
633     * @return a {@code SocketPermission} object representing the
634     *         permission necessary to connect to the destination
635     *         host and port.
636     */
637    public Permission getPermission() throws IOException {
638        int port = url.getPort();
639        port = port < 0 ? 80 : port;
640        String host = url.getHost() + ":" + port;
641        Permission permission = new SocketPermission(host, "connect");
642        return permission;
643    }
644
645   /**
646    * Returns the error stream if the connection failed
647    * but the server sent useful data nonetheless. The
648    * typical example is when an HTTP server responds
649    * with a 404, which will cause a FileNotFoundException
650    * to be thrown in connect, but the server sent an HTML
651    * help page with suggestions as to what to do.
652    *
653    * <p>This method will not cause a connection to be initiated.  If
654    * the connection was not connected, or if the server did not have
655    * an error while connecting or if the server had an error but
656    * no error data was sent, this method will return null. This is
657    * the default.
658    *
659    * @return an error stream if any, null if there have been no
660    * errors, the connection is not connected or the server sent no
661    * useful data.
662    */
663    public InputStream getErrorStream() {
664        return null;
665    }
666
667    /**
668     * The response codes for HTTP, as of version 1.1.
669     */
670
671    // REMIND: do we want all these??
672    // Others not here that we do want??
673
674    /* 2XX: generally "OK" */
675
676    /**
677     * HTTP Status-Code 200: OK.
678     */
679    public static final int HTTP_OK = 200;
680
681    /**
682     * HTTP Status-Code 201: Created.
683     */
684    public static final int HTTP_CREATED = 201;
685
686    /**
687     * HTTP Status-Code 202: Accepted.
688     */
689    public static final int HTTP_ACCEPTED = 202;
690
691    /**
692     * HTTP Status-Code 203: Non-Authoritative Information.
693     */
694    public static final int HTTP_NOT_AUTHORITATIVE = 203;
695
696    /**
697     * HTTP Status-Code 204: No Content.
698     */
699    public static final int HTTP_NO_CONTENT = 204;
700
701    /**
702     * HTTP Status-Code 205: Reset Content.
703     */
704    public static final int HTTP_RESET = 205;
705
706    /**
707     * HTTP Status-Code 206: Partial Content.
708     */
709    public static final int HTTP_PARTIAL = 206;
710
711    /* 3XX: relocation/redirect */
712
713    /**
714     * HTTP Status-Code 300: Multiple Choices.
715     */
716    public static final int HTTP_MULT_CHOICE = 300;
717
718    /**
719     * HTTP Status-Code 301: Moved Permanently.
720     */
721    public static final int HTTP_MOVED_PERM = 301;
722
723    /**
724     * HTTP Status-Code 302: Temporary Redirect.
725     */
726    public static final int HTTP_MOVED_TEMP = 302;
727
728    /**
729     * HTTP Status-Code 303: See Other.
730     */
731    public static final int HTTP_SEE_OTHER = 303;
732
733    /**
734     * HTTP Status-Code 304: Not Modified.
735     */
736    public static final int HTTP_NOT_MODIFIED = 304;
737
738    /**
739     * HTTP Status-Code 305: Use Proxy.
740     */
741    public static final int HTTP_USE_PROXY = 305;
742
743    /* 4XX: client error */
744
745    /**
746     * HTTP Status-Code 400: Bad Request.
747     */
748    public static final int HTTP_BAD_REQUEST = 400;
749
750    /**
751     * HTTP Status-Code 401: Unauthorized.
752     */
753    public static final int HTTP_UNAUTHORIZED = 401;
754
755    /**
756     * HTTP Status-Code 402: Payment Required.
757     */
758    public static final int HTTP_PAYMENT_REQUIRED = 402;
759
760    /**
761     * HTTP Status-Code 403: Forbidden.
762     */
763    public static final int HTTP_FORBIDDEN = 403;
764
765    /**
766     * HTTP Status-Code 404: Not Found.
767     */
768    public static final int HTTP_NOT_FOUND = 404;
769
770    /**
771     * HTTP Status-Code 405: Method Not Allowed.
772     */
773    public static final int HTTP_BAD_METHOD = 405;
774
775    /**
776     * HTTP Status-Code 406: Not Acceptable.
777     */
778    public static final int HTTP_NOT_ACCEPTABLE = 406;
779
780    /**
781     * HTTP Status-Code 407: Proxy Authentication Required.
782     */
783    public static final int HTTP_PROXY_AUTH = 407;
784
785    /**
786     * HTTP Status-Code 408: Request Time-Out.
787     */
788    public static final int HTTP_CLIENT_TIMEOUT = 408;
789
790    /**
791     * HTTP Status-Code 409: Conflict.
792     */
793    public static final int HTTP_CONFLICT = 409;
794
795    /**
796     * HTTP Status-Code 410: Gone.
797     */
798    public static final int HTTP_GONE = 410;
799
800    /**
801     * HTTP Status-Code 411: Length Required.
802     */
803    public static final int HTTP_LENGTH_REQUIRED = 411;
804
805    /**
806     * HTTP Status-Code 412: Precondition Failed.
807     */
808    public static final int HTTP_PRECON_FAILED = 412;
809
810    /**
811     * HTTP Status-Code 413: Request Entity Too Large.
812     */
813    public static final int HTTP_ENTITY_TOO_LARGE = 413;
814
815    /**
816     * HTTP Status-Code 414: Request-URI Too Large.
817     */
818    public static final int HTTP_REQ_TOO_LONG = 414;
819
820    /**
821     * HTTP Status-Code 415: Unsupported Media Type.
822     */
823    public static final int HTTP_UNSUPPORTED_TYPE = 415;
824
825    /* 5XX: server error */
826
827    /**
828     * HTTP Status-Code 500: Internal Server Error.
829     * @deprecated   it is misplaced and shouldn't have existed.
830     */
831    @Deprecated
832    public static final int HTTP_SERVER_ERROR = 500;
833
834    /**
835     * HTTP Status-Code 500: Internal Server Error.
836     */
837    public static final int HTTP_INTERNAL_ERROR = 500;
838
839    /**
840     * HTTP Status-Code 501: Not Implemented.
841     */
842    public static final int HTTP_NOT_IMPLEMENTED = 501;
843
844    /**
845     * HTTP Status-Code 502: Bad Gateway.
846     */
847    public static final int HTTP_BAD_GATEWAY = 502;
848
849    /**
850     * HTTP Status-Code 503: Service Unavailable.
851     */
852    public static final int HTTP_UNAVAILABLE = 503;
853
854    /**
855     * HTTP Status-Code 504: Gateway Timeout.
856     */
857    public static final int HTTP_GATEWAY_TIMEOUT = 504;
858
859    /**
860     * HTTP Status-Code 505: HTTP Version Not Supported.
861     */
862    public static final int HTTP_VERSION = 505;
863
864}
865