1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
218c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilsonimport java.io.InputStream;
220519c0de2e55eeb3566c5ee913a500eb45886f7fElliott Hughesimport java.util.Arrays;
23953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilsonimport libcore.net.http.HttpEngine;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
268c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * An {@link URLConnection} for HTTP (<a
278c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>) used to send and
288c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * receive data over the web. Data may be of any type and length. This class may
298c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * be used to send and receive streaming data whose length is not known in
308c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * advance.
31f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
328c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>Uses of this class follow a pattern:
338c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <ol>
348c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   <li>Obtain a new {@code HttpURLConnection} by calling {@link
358c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       URL#openConnection() URL.openConnection()} and casting the result to
368c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       {@code HttpURLConnection}.
378c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   <li>Prepare the request. The primary property of a request is its URI.
388c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       Request headers may also include metadata such as credentials, preferred
398c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       content types, and session cookies.
408c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   <li>Optionally upload a request body. Instances must be configured with
418c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       {@link #setDoOutput(boolean) setDoOutput(true)} if they include a
428c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       request body. Transmit data by writing to the stream returned by {@link
438c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       #getOutputStream()}.
448c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   <li>Read the response. Response headers typically include metadata such as
458c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       the response body's content type and length, modified dates and session
468c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       cookies. The response body may be read from the stream returned by {@link
478c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       #getInputStream()}. If the response has no body, that method returns an
488c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       empty stream.
498c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   <li>Disconnect. Once the response body has been read, the {@code
508c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       HttpURLConnection} should be closed by calling {@link #disconnect()}.
51eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson *       Disconnecting releases the resources held by a connection so they may
52eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson *       be closed or reused.
538c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * </ol>
548c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
558c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>For example, to retrieve the webpage at {@code http://www.android.com/}:
568c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <pre>   {@code
578c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   URL url = new URL("http://www.android.com/");
588c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
598c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   try {
608c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
618c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     readStream(in);
628c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   } finally {
638c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     urlConnection.disconnect();
648c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   }
658c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * }</pre>
668c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
678c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <h3>Secure Communication with HTTPS</h3>
688bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * Calling {@link URL#openConnection()} on a URL with the "https"
698bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * scheme will return an {@code HttpsURLConnection}, which allows for
708bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * overriding the default {@link javax.net.ssl.HostnameVerifier
718bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * HostnameVerifier} and {@link javax.net.ssl.SSLSocketFactory
728bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * SSLSocketFactory}. An application-supplied {@code SSLSocketFactory}
738bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * created from an {@link javax.net.ssl.SSLContext SSLContext} can
748bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * provide a custom {@link javax.net.ssl.X509TrustManager
758bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * X509TrustManager} for verifying certificate chains and a custom
768bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * {@link javax.net.ssl.X509KeyManager X509KeyManager} for supplying
778bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * client certificates. See {@link javax.net.ssl.HttpsURLConnection
788bccf8cdf7a3b8a6e90bb1b411a957b6368e4a1aBrian Carlstrom * HttpsURLConnection} for more details.
7923e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *
808c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <h3>Response Handling</h3>
818c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * {@code HttpURLConnection} will follow up to five HTTP redirects. It will
8255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * follow redirects from one origin server to another. This implementation
8355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * doesn't follow redirects from HTTPS to HTTP or vice versa.
848c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
8555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <p>If the HTTP response indicates that an error occurred, {@link
8655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * #getInputStream()} will throw an {@link IOException}. Use {@link
8755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * #getErrorStream()} to read the error response. The headers can be read in
8855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * the normal way using {@link #getHeaderFields()},
898c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
908c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <h3>Posting Content</h3>
918c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * To upload data to a web server, configure the connection for output using
928c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * {@link #setDoOutput(boolean) setDoOutput(true)}.
938c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
948c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>For best performance, you should call either {@link
958c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * #setFixedLengthStreamingMode(int)} when the body length is known in advance,
968c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * or {@link #setChunkedStreamingMode(int)} when it is not. Otherwise {@code
978c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * HttpURLConnection} will be forced to buffer the complete request body in
988c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * memory before it is transmitted, wasting (and possibly exhausting) heap and
998c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * increasing latency.
1008c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
10123e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * <p>For example, to perform an upload: <pre>   {@code
1028c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
1038c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   try {
1048c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     urlConnection.setDoOutput(true);
10555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *     urlConnection.setChunkedStreamingMode(0);
1068c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
1078c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
1088c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     writeStream(out);
1098c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
1108c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
1118c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     readStream(in);
1128c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   } finally {
1138c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     urlConnection.disconnect();
1148c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   }
1158c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * }</pre>
1168c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
11755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <h3>Performance</h3>
11855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * The input and output streams returned by this class are <strong>not
11955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * buffered</strong>. Most callers should wrap the returned streams with {@link
12055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * java.io.BufferedInputStream BufferedInputStream} or {@link
12155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * java.io.BufferedOutputStream BufferedOutputStream}. Callers that do only bulk
12255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * reads or writes may omit buffering.
12355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *
12455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <p>When transferring large amounts of data to or from a server, use streams
12555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * to limit how much data is in memory at once. Unless you need the entire
12655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * body to be in memory at once, process it as a stream (rather than storing
12755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * the complete body as a single byte array or string).
12855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *
12955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <p>To reduce latency, this class may reuse the same underlying {@code Socket}
13055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * for multiple request/response pairs. As a result, HTTP connections may be
131eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson * held open longer than necessary. Calls to {@link #disconnect()} may return
132eb09bc383703f0b2d6c99daf83479d5ce573a2f9Jesse Wilson * the socket to a pool of connected sockets. This behavior can be disabled by
1332d9fa917aae6a6da38e9d1eda05841ffdf8855bbJesse Wilson * setting the {@code http.keepAlive} system property to {@code false} before
1342d9fa917aae6a6da38e9d1eda05841ffdf8855bbJesse Wilson * issuing any HTTP requests. The {@code http.maxConnections} property may be
1352d9fa917aae6a6da38e9d1eda05841ffdf8855bbJesse Wilson * used to control how many idle connections to each server will be held.
13655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *
13755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <p>By default, this implementation of {@code HttpURLConnection} requests that
13855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * servers use gzip compression. Since {@link #getContentLength()} returns the
13955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * number of bytes transmitted, you cannot use that method to predict how many
14055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * bytes can be read from {@link #getInputStream()}. Instead, read that stream
14155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * until it is exhausted: when {@link InputStream#read} returns -1. Gzip
14255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * compression can be disabled by setting the acceptable encodings in the
14355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * request header: <pre>   {@code
14455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *   urlConnection.setRequestProperty("Accept-Encoding", "identity");
14555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * }</pre>
14655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *
14723e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * <h3>Handling Network Sign-On</h3>
14823e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * Some Wi-Fi networks block Internet access until the user clicks through a
14923e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * sign-on page. Such sign-on pages are typically presented by using HTTP
15023e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * redirects. You can use {@link #getURL()} to test if your connection has been
15123e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * unexpectedly redirected. This check is not valid until <strong>after</strong>
15223e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * the response headers have been received, which you can trigger by calling
15323e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * {@link #getHeaderFields()} or {@link #getInputStream()}. For example, to
15423e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * check that a response was not redirected to an unexpected host:
15523e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * <pre>   {@code
15623e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
15723e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *   try {
15823e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
15923e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
16023e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *       // we were redirected! Kick the user out to the browser to sign on?
16123e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *     }
16223e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *     ...
16323e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *   } finally {
16423e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *     urlConnection.disconnect();
16523e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *   }
16623e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson * }</pre>
16723e3c8dad87724420bad70e9e9c4e8b94a565f14Jesse Wilson *
1688c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <h3>HTTP Authentication</h3>
1698c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * {@code HttpURLConnection} supports <a
1708c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * href="http://www.ietf.org/rfc/rfc2617">HTTP basic authentication</a>. Use
1718c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * {@link Authenticator} to set the VM-wide authentication handler:
1728c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <pre>   {@code
1738c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   Authenticator.setDefault(new Authenticator() {
1748c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     protected PasswordAuthentication getPasswordAuthentication() {
1758c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *       return new PasswordAuthentication(username, password.toCharArray());
1768c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *     }
1778c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   });
1788c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * }</pre>
1798c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * Unless paired with HTTPS, this is <strong>not</strong> a secure mechanism for
1808c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * user authentication. In particular, the username, password, request and
1818c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * response are all transmitted over the network without encryption.
1828c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
1838c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <h3>Sessions with Cookies</h3>
1848c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * To establish and maintain a potentially long-lived session between client
1858c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * and server, {@code HttpURLConnection} includes an extensible cookie manager.
1868c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * Enable VM-wide cookie management using {@link CookieHandler} and {@link
1878c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * CookieManager}: <pre>   {@code
1888c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   CookieManager cookieManager = new CookieManager();
1898c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   CookieHandler.setDefault(cookieManager);
1908c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * }</pre>
1918c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * By default, {@code CookieManager} accepts cookies from the <a
1928c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
1938c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * server</a> only. Two other policies are included: {@link
1948c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * CookiePolicy#ACCEPT_ALL} and {@link CookiePolicy#ACCEPT_NONE}. Implement
1958c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * {@link CookiePolicy} to define a custom policy.
1968c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
1978c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>The default {@code CookieManager} keeps all accepted cookies in memory. It
1988c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * will forget these cookies when the VM exits. Implement {@link CookieStore} to
1998c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * define a custom cookie store.
2008c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
2018c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>In addition to the cookies set by HTTP responses, you may set cookies
2028c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * programmatically. To be included in HTTP request headers, cookies must have
20355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * the domain and path properties set.
20455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *
20555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <p>By default, new instances of {@code HttpCookie} work only with servers
20655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * that support <a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>
20755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * cookies. Many web servers support only the older specification, <a
20855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a>. For compatibility
20955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * with the most web servers, set the cookie version to 0.
21055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson *
21155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <p>For example, to receive {@code www.twitter.com} in French: <pre>   {@code
2128c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   HttpCookie cookie = new HttpCookie("lang", "fr");
2138c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   cookie.setDomain("twitter.com");
2148c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   cookie.setPath("/");
2158c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   cookie.setVersion(0);
2168c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *   cookieManager.getCookieStore().add(new URI("http://twitter.com/"), cookie);
21755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * }</pre>
2188c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
21911b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson * <h3>HTTP Methods</h3>
22011b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson * <p>{@code HttpURLConnection} uses the {@code GET} method by default. It will
22111b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson * use {@code POST} if {@link #setDoOutput setDoOutput(true)} has been called.
22211b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson * Other HTTP methods ({@code OPTIONS}, {@code HEAD}, {@code PUT}, {@code
22311b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson * DELETE} and {@code TRACE}) can be used with {@link #setRequestMethod}.
22411b9d26222315d4ddea223ce8f119ec25a1ba3d5Jesse Wilson *
22555bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <h3>Proxies</h3>
2268c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * By default, this class will connect directly to the <a
2278c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
2288c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * server</a>. It can also connect via an {@link Proxy.Type#HTTP HTTP} or {@link
2298c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * Proxy.Type#SOCKS SOCKS} proxy. To use a proxy, use {@link
2308c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * URL#openConnection(Proxy) URL.openConnection(Proxy)} when creating the
2318c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * connection.
2328c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
23355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <h3>IPv6 Support</h3>
2348c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>This class includes transparent support for IPv6. For hosts with both IPv4
2358c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * and IPv6 addresses, it will attempt to connect to each of a host's addresses
2368c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * until a connection is established.
2378c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
23855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson * <h3>Response Caching</h3>
239ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * Android 4.0 (Ice Cream Sandwich) includes a response cache. See {@code
240ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * android.net.http.HttpResponseCache} for instructions on enabling HTTP caching
241ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * in your application.
242ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson *
243ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * <h3>Avoiding Bugs In Earlier Releases</h3>
244ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * Prior to Android 2.2 (Froyo), this class had some frustrating bugs. In
245ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * particular, calling {@code close()} on a readable {@code InputStream} could
246ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * <a href="http://code.google.com/p/android/issues/detail?id=2939">poison the
247ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * connection pool</a>. Work around this by disabling connection pooling:
248ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * <pre>   {@code
249ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * private void disableConnectionReuseIfNecessary() {
250ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson *   // Work around pre-Froyo bugs in HTTP connection reuse.
251ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson *   if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
252ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson *     System.setProperty("http.keepAlive", "false");
253ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson *   }
254ab7ae56666faffd5ad7aecfc07500ad5f4983ff2Jesse Wilson * }}</pre>
2558c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson *
2568c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * <p>Each instance of {@code HttpURLConnection} may be used for one
2578c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson * request/response pair. Instances of this class are not thread safe.
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class HttpURLConnection extends URLConnection {
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
261c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson    /**
262953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson     * The subset of HTTP methods that the user may select via {@link
263d742d7fc7f0593eb8c6e4ac9dd4c0f6a80374e46Jesse Wilson     * #setRequestMethod(String)}.
264953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson     */
265953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson    private static final String[] PERMITTED_USER_METHODS = {
266953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.OPTIONS,
267953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.GET,
268953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.HEAD,
269953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.POST,
270953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.PUT,
271953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.DELETE,
272953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            HttpEngine.TRACE
273953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            // Note: we don't allow users to specify "CONNECT"
274953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson    };
275953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson
276953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson    /**
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The HTTP request method of this {@code HttpURLConnection}. The default
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value is {@code "GET"}.
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
280953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson    protected String method = HttpEngine.GET;
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The status code of the response obtained from the HTTP request. The
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * default value is {@code -1}.
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>1xx: Informational</li>
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>2xx: Success</li>
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>3xx: Relocation/Redirection</li>
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>4xx: Client Error</li>
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>5xx: Server Error</li>
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected int responseCode = -1;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The HTTP response message which corresponds to the response code.
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected String responseMessage;
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Flag to define whether the protocol will automatically follow redirects
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or not. The default value is {@code true}.
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected boolean instanceFollowRedirects = followRedirects;
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static boolean followRedirects = true;
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the HTTP chunked encoding is enabled this parameter defines the
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * chunk-length. Default value is {@code -1} that means the chunked encoding
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * mode is disabled.
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected int chunkLength = -1;
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If using HTTP fixed-length streaming mode this parameter defines the
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * fixed length of content. Default value is {@code -1} that means the
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * fixed-length streaming mode is disabled.
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected int fixedContentLength = -1;
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // 2XX: generally "OK"
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // 3XX: relocation/redirect
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // 4XX: client error
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // 5XX: server error
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 202: Accepted
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3280d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_ACCEPTED = 202;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 502: Bad Gateway
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3330d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_BAD_GATEWAY = 502;
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 405: Bad Method
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3380d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_BAD_METHOD = 405;
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 400: Bad Request
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3430d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_BAD_REQUEST = 400;
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 408: Client Timeout
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3480d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_CLIENT_TIMEOUT = 408;
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 409: Conflict
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3530d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_CONFLICT = 409;
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 201: Created
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3580d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_CREATED = 201;
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 413: Entity too large
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3630d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_ENTITY_TOO_LARGE = 413;
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 403: Forbidden
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3680d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_FORBIDDEN = 403;
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 504: Gateway timeout
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3730d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_GATEWAY_TIMEOUT = 504;
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 410: Gone
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3780d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_GONE = 410;
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 500: Internal error
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3830d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_INTERNAL_ERROR = 500;
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 411: Length required
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3880d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_LENGTH_REQUIRED = 411;
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 301 Moved permanently
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3930d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_MOVED_PERM = 301;
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 302: Moved temporarily
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3980d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_MOVED_TEMP = 302;
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 300: Multiple choices
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4030d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_MULT_CHOICE = 300;
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 204: No content
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4080d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_NO_CONTENT = 204;
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 406: Not acceptable
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4130d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_NOT_ACCEPTABLE = 406;
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 203: Not authoritative
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4180d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_NOT_AUTHORITATIVE = 203;
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 404: Not found
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4230d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_NOT_FOUND = 404;
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 501: Not implemented
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4280d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_NOT_IMPLEMENTED = 501;
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 304: Not modified
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4330d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_NOT_MODIFIED = 304;
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 200: OK
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4380d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_OK = 200;
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 206: Partial
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4430d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_PARTIAL = 206;
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 402: Payment required
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4480d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_PAYMENT_REQUIRED = 402;
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 412: Precondition failed
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4530d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_PRECON_FAILED = 412;
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 407: Proxy authentication required
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4580d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_PROXY_AUTH = 407;
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 414: Request too long
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4630d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_REQ_TOO_LONG = 414;
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 205: Reset
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4680d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_RESET = 205;
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 303: See other
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4730d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_SEE_OTHER = 303;
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 500: Internal error
477f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@link #HTTP_INTERNAL_ERROR}
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
4810d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_SERVER_ERROR = 500;
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
484d742d7fc7f0593eb8c6e4ac9dd4c0f6a80374e46Jesse Wilson     * Numeric status code, 305: Use proxy.
485d742d7fc7f0593eb8c6e4ac9dd4c0f6a80374e46Jesse Wilson     *
486d742d7fc7f0593eb8c6e4ac9dd4c0f6a80374e46Jesse Wilson     * <p>Like Firefox and Chrome, this class doesn't honor this response code.
487d742d7fc7f0593eb8c6e4ac9dd4c0f6a80374e46Jesse Wilson     * Other implementations respond to this status code by retrying the request
488d742d7fc7f0593eb8c6e4ac9dd4c0f6a80374e46Jesse Wilson     * using the HTTP proxy named by the response's Location header field.
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4900d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_USE_PROXY = 305;
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 401: Unauthorized
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
4950d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_UNAUTHORIZED = 401;
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 415: Unsupported type
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
5000d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_UNSUPPORTED_TYPE = 415;
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 503: Unavailable
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
5050d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_UNAVAILABLE = 503;
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Numeric status code, 505: Version not supported
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
5100d4ce4227fa818288b8db762b640dfa21e3162f5Elliott Hughes    public static final int HTTP_VERSION = 505;
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code HttpURLConnection} instance pointing to the
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * resource specified by the {@code url}.
515f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param url
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the URL of this connection.
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see URL
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see URLConnection
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected HttpURLConnection(URL url) {
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(url);
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
5260613de89655e481fa610bfd4f1bcaeeae3272205Jesse Wilson     * Releases this connection so that its resources may be either reused or
5270613de89655e481fa610bfd4f1bcaeeae3272205Jesse Wilson     * closed.
528f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
5290613de89655e481fa610bfd4f1bcaeeae3272205Jesse Wilson     * <p>Unlike other Java implementations, this will not necessarily close
5301ce4f4b41b4b52e50bee1f4c4912ccede16877cfJesse Wilson     * socket connections that can be reused. You can disable all connection
5312d9fa917aae6a6da38e9d1eda05841ffdf8855bbJesse Wilson     * reuse by setting the {@code http.keepAlive} system property to {@code
5322d9fa917aae6a6da38e9d1eda05841ffdf8855bbJesse Wilson     * false} before issuing any HTTP requests.
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract void disconnect();
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns an input stream from the server in the case of an error such as
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the requested file has not been found on the remote server. This stream
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * can be used to read the data the server will send back.
540f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the error input stream returned by the server.
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
5438c283b62cd1952ffa145332d94ed691acf4ac87eJesse Wilson    public InputStream getErrorStream() {
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the value of {@code followRedirects} which indicates if this
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connection follows a different URL redirected by the server. It is
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * enabled by default.
551f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the flag.
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setFollowRedirects
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static boolean getFollowRedirects() {
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return followRedirects;
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the permission object (in this case {@code SocketPermission})
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * with the host and the port number as the target name and {@code
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * "resolve, connect"} as the action list. If the port number of this URL
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instance is lower than {@code 0} the port will be set to {@code 80}.
564f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the permission object required for this connection.
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an IO exception occurs during the creation of the
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             permission object.
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public java.security.Permission getPermission() throws IOException {
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = url.getPort();
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (port < 0) {
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            port = 80;
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
576f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return new SocketPermission(url.getHost() + ":" + port,
577f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                "connect, resolve");
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the request method which will be used to make the request to the
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * remote HTTP server. All possible methods of this HTTP implementation is
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * listed in the class definition.
584f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the request method string.
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #method
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setRequestMethod
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getRequestMethod() {
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return method;
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the response code returned by the remote HTTP server.
595f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the response code, -1 if no valid response code.
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is an IO error during the retrieval.
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getResponseMessage
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getResponseCode() throws IOException {
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Call getInputStream() first since getHeaderField() doesn't return
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // exceptions
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        getInputStream();
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String response = getHeaderField(0);
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (response == null) {
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        response = response.trim();
610f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        int mark = response.indexOf(" ") + 1;
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (mark == 0) {
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int last = mark + 3;
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (last > response.length()) {
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            last = response.length();
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        responseCode = Integer.parseInt(response.substring(mark, last));
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (last + 1 <= response.length()) {
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            responseMessage = response.substring(last + 1);
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return responseCode;
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the response message returned by the remote HTTP server.
627f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the response message. {@code null} if no such response exists.
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if there is an error during the retrieval.
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getResponseCode()
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getResponseMessage() throws IOException {
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (responseMessage != null) {
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return responseMessage;
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        getResponseCode();
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return responseMessage;
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the flag of whether this connection will follow redirects returned
64387548e8585334658c3ee89050ec917a10ca35e5aElliott Hughes     * by the remote server.
644f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param auto
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value to enable or disable this option.
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static void setFollowRedirects(boolean auto) {
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        followRedirects = auto;
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the request command which will be sent to the remote HTTP server.
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method can only be called before the connection is made.
655f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param method
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the string representing the method to be used.
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ProtocolException
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this is called after connected, or the method is not
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             supported by this HTTP implementation.
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #getRequestMethod()
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #method
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setRequestMethod(String method) throws ProtocolException {
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (connected) {
666b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new ProtocolException("Connection already established");
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
668953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson        for (String permittedUserMethod : PERMITTED_USER_METHODS) {
669c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson            if (permittedUserMethod.equals(method)) {
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // if there is a supported method that matches the desired
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // method, then set the current method and return
672c8977f474b30c5f3807398859a6b16687af6fc7bJesse Wilson                this.method = permittedUserMethod;
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // if none matches, then throw ProtocolException
6770519c0de2e55eeb3566c5ee913a500eb45886f7fElliott Hughes        throw new ProtocolException("Unknown method '" + method + "'; must be one of " +
678953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson                Arrays.toString(PERMITTED_USER_METHODS));
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this connection uses a proxy server or not.
683f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this connection passes a proxy server, false
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public abstract boolean usingProxy();
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
690d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson     * Returns the encoding used to transmit the response body over the network.
691d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson     * This is null or "identity" if the content was not encoded, or "gzip" if
692d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson     * the body was gzip compressed. Most callers will be more interested in the
693d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson     * {@link #getContentType() content type}, which may also include the
694d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson     * content's character encoding.
695d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson     */
696d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson    @Override public String getContentEncoding() {
697d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson        return super.getContentEncoding(); // overridden for Javadoc only
698d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson    }
699d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson
700d4bddd7d1fb7b1b7f0836648228235c6e4b56a18Jesse Wilson    /**
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this connection follows redirects.
702f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this connection follows redirects, false
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise.
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getInstanceFollowRedirects() {
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return instanceFollowRedirects;
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets whether this connection follows redirects.
712f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param followRedirects
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code true} if this connection will follows redirects, false
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            otherwise.
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setInstanceFollowRedirects(boolean followRedirects) {
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        instanceFollowRedirects = followRedirects;
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the date value in milliseconds since {@code 01.01.1970, 00:00h}
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * corresponding to the header field {@code field}. The {@code defaultValue}
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will be returned if no such field can be found in the response header.
725f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param field
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the header field name.
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param defaultValue
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the default value to use if the specified header field wont be
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            found.
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the header field represented in milliseconds since January 1,
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         1970 GMT.
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public long getHeaderFieldDate(String field, long defaultValue) {
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return super.getHeaderFieldDate(field, defaultValue);
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the length of a HTTP request body is known ahead, sets fixed length to
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * enable streaming without buffering. Sets after connection will cause an
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exception.
743f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setChunkedStreamingMode
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param contentLength
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the fixed length of the HTTP request body.
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
7481208f030332b3e1eae3d55d416f1af1d68f7e33dElliott Hughes     *             if already connected or another mode already set.
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code contentLength} is less than zero.
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setFixedLengthStreamingMode(int contentLength) {
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (super.connected) {
754b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalStateException("Already connected");
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
756b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (chunkLength > 0) {
757b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalStateException("Already in chunked mode");
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
759b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (contentLength < 0) {
760b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("contentLength < 0");
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.fixedContentLength = contentLength;
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
76655bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * Stream a request body whose length is not known in advance. Old HTTP/1.0
76755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * only servers may not support this mode.
76855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     *
76955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * <p>When HTTP chunked encoding is used, the stream is divided into
77055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * chunks, each prefixed with a header containing the chunk's size. Setting
77155bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * a large chunk length requires a large internal buffer, potentially
77255bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * wasting memory. Setting a small chunk length increases the number of
77355bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * bytes that must be transmitted because of the header on every chunk.
77455bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * Most caller should use {@code 0} to get the system default.
775f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setFixedLengthStreamingMode
77755bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * @param chunkLength the length to use, or {@code 0} for the default chunk
77855bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     *     length.
77955bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     * @throws IllegalStateException if already connected or another mode
78055bbb57dc76ab0231583460f5af4083f4f48f8f5Jesse Wilson     *     already set.
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
782ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson    public void setChunkedStreamingMode(int chunkLength) {
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (super.connected) {
784b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalStateException("Already connected");
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
786ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson        if (fixedContentLength >= 0) {
787b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalStateException("Already in fixed-length mode");
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
789ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson        if (chunkLength <= 0) {
790953df613522e12a418cb7cb73248594d6c9f53d4Jesse Wilson            this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
792ffd579b668428272b78f5c6c64f9c89766f37c1aJesse Wilson            this.chunkLength = chunkLength;
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
796