1c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath/*
2c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  Licensed to the Apache Software Foundation (ASF) under one or more
3c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  contributor license agreements.  See the NOTICE file distributed with
4c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  this work for additional information regarding copyright ownership.
5c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  The ASF licenses this file to You under the Apache License, Version 2.0
6c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  (the "License"); you may not use this file except in compliance with
7c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  the License.  You may obtain a copy of the License at
8c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
9c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     http://www.apache.org/licenses/LICENSE-2.0
10c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
11c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  Unless required by applicable law or agreed to in writing, software
12c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  distributed under the License is distributed on an "AS IS" BASIS,
13c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  See the License for the specific language governing permissions and
15c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *  limitations under the License.
16c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath */
17c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
18c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathpackage com.squareup.okhttp;
19c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
20c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.io.IOException;
21c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.io.InputStream;
22c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.net.ProtocolException;
23c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.net.Proxy;
24c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.net.SocketPermission;
25c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.net.URL;
26c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.net.URLConnection;
27c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport java.util.Arrays;
28c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathimport libcore.net.http.HttpEngine;
29c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
30c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath/**
31c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * An {@link java.net.URLConnection} for HTTP (<a
32c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>) used to send and
33c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * receive data over the web. Data may be of any type and length. This class may
34c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * be used to send and receive streaming data whose length is not known in
35c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * advance.
36c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
37c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>Uses of this class follow a pattern:
38c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <ol>
39c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   <li>Obtain a new {@code HttpURLConnection} by calling {@link
40c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       java.net.URL#openConnection() URL.openConnection()} and casting the result to
41c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       {@code HttpURLConnection}.
42c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   <li>Prepare the request. The primary property of a request is its URI.
43c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       Request headers may also include metadata such as credentials, preferred
44c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       content types, and session cookies.
45c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   <li>Optionally upload a request body. Instances must be configured with
46c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       {@link #setDoOutput(boolean) setDoOutput(true)} if they include a
47c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       request body. Transmit data by writing to the stream returned by {@link
48c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       #getOutputStream()}.
49c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   <li>Read the response. Response headers typically include metadata such as
50c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       the response body's content type and length, modified dates and session
51c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       cookies. The response body may be read from the stream returned by {@link
52c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       #getInputStream()}. If the response has no body, that method returns an
53c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       empty stream.
54c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   <li>Disconnect. Once the response body has been read, the {@code
55c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       HttpURLConnection} should be closed by calling {@link #disconnect()}.
56c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       Disconnecting releases the resources held by a connection so they may
57c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       be closed or reused.
58c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * </ol>
59c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
60c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>For example, to retrieve the webpage at {@code http://www.android.com/}:
61c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <pre>   {@code
62c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   URL url = new URL("http://www.android.com/");
63c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
64c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   try {
65c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
66c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     readStream(in);
67c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   } finally {
68c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     urlConnection.disconnect();
69c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   }
70c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
71c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
72c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Secure Communication with HTTPS</h3>
73c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Calling {@link java.net.URL#openConnection()} on a URL with the "https"
74c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * scheme will return an {@code HttpsURLConnection}, which allows for
75c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * overriding the default {@link javax.net.ssl.HostnameVerifier
76c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * HostnameVerifier} and {@link javax.net.ssl.SSLSocketFactory
77c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * SSLSocketFactory}. An application-supplied {@code SSLSocketFactory}
78c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * created from an {@link javax.net.ssl.SSLContext SSLContext} can
79c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * provide a custom {@link javax.net.ssl.X509TrustManager
80c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * X509TrustManager} for verifying certificate chains and a custom
81c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@link javax.net.ssl.X509KeyManager X509KeyManager} for supplying
82c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * client certificates. See {@link OkHttpsConnection HttpsURLConnection} for
83c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * more details.
84c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
85c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Response Handling</h3>
86c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@code HttpURLConnection} will follow up to five HTTP redirects. It will
87c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * follow redirects from one origin server to another. This implementation
88c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * doesn't follow redirects from HTTPS to HTTP or vice versa.
89c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
90c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>If the HTTP response indicates that an error occurred, {@link
91c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * #getInputStream()} will throw an {@link java.io.IOException}. Use {@link
92c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * #getErrorStream()} to read the error response. The headers can be read in
93c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * the normal way using {@link #getHeaderFields()},
94c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
95c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Posting Content</h3>
96c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * To upload data to a web server, configure the connection for output using
97c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@link #setDoOutput(boolean) setDoOutput(true)}.
98c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
99c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>For best performance, you should call either {@link
100c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * #setFixedLengthStreamingMode(int)} when the body length is known in advance,
101c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * or {@link #setChunkedStreamingMode(int)} when it is not. Otherwise {@code
102c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * HttpURLConnection} will be forced to buffer the complete request body in
103c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * memory before it is transmitted, wasting (and possibly exhausting) heap and
104c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * increasing latency.
105c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
106c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>For example, to perform an upload: <pre>   {@code
107c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
108c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   try {
109c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     urlConnection.setDoOutput(true);
110c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     urlConnection.setChunkedStreamingMode(0);
111c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
112c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
113c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     writeStream(out);
114c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
115c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
116c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     readStream(in);
117c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   } finally {
118c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     urlConnection.disconnect();
119c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   }
120c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
121c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
122c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Performance</h3>
123c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * The input and output streams returned by this class are <strong>not
124c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * buffered</strong>. Most callers should wrap the returned streams with {@link
125c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * java.io.BufferedInputStream BufferedInputStream} or {@link
126c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * java.io.BufferedOutputStream BufferedOutputStream}. Callers that do only bulk
127c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * reads or writes may omit buffering.
128c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
129c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>When transferring large amounts of data to or from a server, use streams
130c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * to limit how much data is in memory at once. Unless you need the entire
131c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * body to be in memory at once, process it as a stream (rather than storing
132c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * the complete body as a single byte array or string).
133c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
134c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>To reduce latency, this class may reuse the same underlying {@code Socket}
135c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * for multiple request/response pairs. As a result, HTTP connections may be
136c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * held open longer than necessary. Calls to {@link #disconnect()} may return
137c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * the socket to a pool of connected sockets. This behavior can be disabled by
138c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * setting the {@code http.keepAlive} system property to {@code false} before
139c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * issuing any HTTP requests. The {@code http.maxConnections} property may be
140c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * used to control how many idle connections to each server will be held.
141c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
142c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>By default, this implementation of {@code HttpURLConnection} requests that
143c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * servers use gzip compression. Since {@link #getContentLength()} returns the
144c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * number of bytes transmitted, you cannot use that method to predict how many
145c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * bytes can be read from {@link #getInputStream()}. Instead, read that stream
146c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * until it is exhausted: when {@link java.io.InputStream#read} returns -1. Gzip
147c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * compression can be disabled by setting the acceptable encodings in the
148c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * request header: <pre>   {@code
149c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   urlConnection.setRequestProperty("Accept-Encoding", "identity");
150c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
151c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
152c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Handling Network Sign-On</h3>
153c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Some Wi-Fi networks block Internet access until the user clicks through a
154c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * sign-on page. Such sign-on pages are typically presented by using HTTP
155c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * redirects. You can use {@link #getURL()} to test if your connection has been
156c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * unexpectedly redirected. This check is not valid until <strong>after</strong>
157c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * the response headers have been received, which you can trigger by calling
158c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@link #getHeaderFields()} or {@link #getInputStream()}. For example, to
159c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * check that a response was not redirected to an unexpected host:
160c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <pre>   {@code
161c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
162c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   try {
163c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
164c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
165c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       // we were redirected! Kick the user out to the browser to sign on?
166c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     }
167c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     ...
168c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   } finally {
169c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     urlConnection.disconnect();
170c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   }
171c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
172c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
173c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>HTTP Authentication</h3>
174c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@code HttpURLConnection} supports <a
175c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * href="http://www.ietf.org/rfc/rfc2617">HTTP basic authentication</a>. Use
176c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@link java.net.Authenticator} to set the VM-wide authentication handler:
177c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <pre>   {@code
178c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   Authenticator.setDefault(new Authenticator() {
179c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     protected PasswordAuthentication getPasswordAuthentication() {
180c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *       return new PasswordAuthentication(username, password.toCharArray());
181c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     }
182c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   });
183c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
184c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Unless paired with HTTPS, this is <strong>not</strong> a secure mechanism for
185c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * user authentication. In particular, the username, password, request and
186c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * response are all transmitted over the network without encryption.
187c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
188c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Sessions with Cookies</h3>
189c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * To establish and maintain a potentially long-lived session between client
190c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * and server, {@code HttpURLConnection} includes an extensible cookie manager.
191c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Enable VM-wide cookie management using {@link java.net.CookieHandler} and {@link
192c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * java.net.CookieManager}: <pre>   {@code
193c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   CookieManager cookieManager = new CookieManager();
194c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   CookieHandler.setDefault(cookieManager);
195c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
196c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * By default, {@code CookieManager} accepts cookies from the <a
197c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
198c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * server</a> only. Two other policies are included: {@link
199c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * java.net.CookiePolicy#ACCEPT_ALL} and {@link java.net.CookiePolicy#ACCEPT_NONE}. Implement
200c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * {@link java.net.CookiePolicy} to define a custom policy.
201c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
202c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>The default {@code CookieManager} keeps all accepted cookies in memory. It
203c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * will forget these cookies when the VM exits. Implement {@link java.net.CookieStore} to
204c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * define a custom cookie store.
205c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
206c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>In addition to the cookies set by HTTP responses, you may set cookies
207c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * programmatically. To be included in HTTP request headers, cookies must have
208c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * the domain and path properties set.
209c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
210c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>By default, new instances of {@code HttpCookie} work only with servers
211c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * that support <a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>
212c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * cookies. Many web servers support only the older specification, <a
213c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a>. For compatibility
214c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * with the most web servers, set the cookie version to 0.
215c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
216c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>For example, to receive {@code www.twitter.com} in French: <pre>   {@code
217c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   HttpCookie cookie = new HttpCookie("lang", "fr");
218c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   cookie.setDomain("twitter.com");
219c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   cookie.setPath("/");
220c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   cookie.setVersion(0);
221c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   cookieManager.getCookieStore().add(new URI("http://twitter.com/"), cookie);
222c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }</pre>
223c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
224c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>HTTP Methods</h3>
225c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>{@code HttpURLConnection} uses the {@code GET} method by default. It will
226c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * use {@code POST} if {@link #setDoOutput setDoOutput(true)} has been called.
227c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Other HTTP methods ({@code OPTIONS}, {@code HEAD}, {@code PUT}, {@code
228c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * DELETE} and {@code TRACE}) can be used with {@link #setRequestMethod}.
229c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
230c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Proxies</h3>
231c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * By default, this class will connect directly to the <a
232c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
233c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * server</a>. It can also connect via an {@link java.net.Proxy.Type#HTTP HTTP} or {@link
234c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * java.net.Proxy.Type#SOCKS SOCKS} proxy. To use a proxy, use {@link
235c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * java.net.URL#openConnection(java.net.Proxy) URL.openConnection(Proxy)} when creating the
236c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * connection.
237c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
238c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>IPv6 Support</h3>
239c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>This class includes transparent support for IPv6. For hosts with both IPv4
240c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * and IPv6 addresses, it will attempt to connect to each of a host's addresses
241c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * until a connection is established.
242c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
243c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Response Caching</h3>
244c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Android 4.0 (Ice Cream Sandwich) includes a response cache. See {@code
245c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * android.net.http.HttpResponseCache} for instructions on enabling HTTP caching
246c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * in your application.
247c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
248c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <h3>Avoiding Bugs In Earlier Releases</h3>
249c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * Prior to Android 2.2 (Froyo), this class had some frustrating bugs. In
250c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * particular, calling {@code close()} on a readable {@code InputStream} could
251c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <a href="http://code.google.com/p/android/issues/detail?id=2939">poison the
252c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * connection pool</a>. Work around this by disabling connection pooling:
253c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <pre>   {@code
254c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * private void disableConnectionReuseIfNecessary() {
255c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   // Work around pre-Froyo bugs in HTTP connection reuse.
256c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
257c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *     System.setProperty("http.keepAlive", "false");
258c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *   }
259c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * }}</pre>
260c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath *
261c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * <p>Each instance of {@code HttpURLConnection} may be used for one
262c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath * request/response pair. Instances of this class are not thread safe.
263c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath */
264c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamathpublic abstract class OkHttpConnection extends URLConnection {
265c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
266c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
267c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * The subset of HTTP methods that the user may select via {@link
268c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * #setRequestMethod(String)}.
269c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
270c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    private static final String[] PERMITTED_USER_METHODS = {
271c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.OPTIONS,
272c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.GET,
273c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.HEAD,
274c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.POST,
275c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.PUT,
276c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.DELETE,
277c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            HttpEngine.TRACE
278c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            // Note: we don't allow users to specify "CONNECT"
279c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    };
280c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
281c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
282c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * The HTTP request method of this {@code HttpURLConnection}. The default
283c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * value is {@code "GET"}.
284c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
285c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected String method = HttpEngine.GET;
286c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
287c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
288c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * The status code of the response obtained from the HTTP request. The
289c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * default value is {@code -1}.
290c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <p>
291c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <li>1xx: Informational</li>
292c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <li>2xx: Success</li>
293c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <li>3xx: Relocation/Redirection</li>
294c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <li>4xx: Client Error</li>
295c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <li>5xx: Server Error</li>
296c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
297c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected int responseCode = -1;
298c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
299c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
300c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * The HTTP response message which corresponds to the response code.
301c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
302c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected String responseMessage;
303c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
304c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
305c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Flag to define whether the protocol will automatically follow redirects
306c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * or not. The default value is {@code true}.
307c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
308c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected boolean instanceFollowRedirects = followRedirects;
309c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
310c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    private static boolean followRedirects = true;
311c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
312c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
313c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * If the HTTP chunked encoding is enabled this parameter defines the
314c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * chunk-length. Default value is {@code -1} that means the chunked encoding
315c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * mode is disabled.
316c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
317c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected int chunkLength = -1;
318c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
319c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
320c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * If using HTTP fixed-length streaming mode this parameter defines the
321c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * fixed length of content. Default value is {@code -1} that means the
322c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * fixed-length streaming mode is disabled.
323c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
324c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected int fixedContentLength = -1;
325c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
326c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    // 2XX: generally "OK"
327c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    // 3XX: relocation/redirect
328c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    // 4XX: client error
329c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    // 5XX: server error
330c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
331c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 202: Accepted.
332c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
333c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_ACCEPTED = 202;
334c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
335c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
336c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 502: Bad Gateway.
337c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
338c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_BAD_GATEWAY = 502;
339c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
340c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
341c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 405: Bad Method.
342c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
343c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_BAD_METHOD = 405;
344c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
345c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
346c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 400: Bad Request.
347c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
348c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_BAD_REQUEST = 400;
349c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
350c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
351c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 408: Client Timeout.
352c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
353c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_CLIENT_TIMEOUT = 408;
354c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
355c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
356c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 409: Conflict.
357c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
358c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_CONFLICT = 409;
359c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
360c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
361c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 201: Created.
362c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
363c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_CREATED = 201;
364c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
365c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
366c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 413: Entity too large.
367c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
368c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_ENTITY_TOO_LARGE = 413;
369c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
370c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
371c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 403: Forbidden.
372c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
373c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_FORBIDDEN = 403;
374c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
375c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
376c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 504: Gateway timeout.
377c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
378c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_GATEWAY_TIMEOUT = 504;
379c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
380c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
381c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 410: Gone.
382c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
383c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_GONE = 410;
384c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
385c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
386c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 500: Internal error.
387c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
388c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_INTERNAL_ERROR = 500;
389c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
390c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
391c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 411: Length required.
392c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
393c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_LENGTH_REQUIRED = 411;
394c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
395c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
396c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 301 Moved permanently.
397c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
398c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_MOVED_PERM = 301;
399c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
400c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
401c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 302: Moved temporarily.
402c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
403c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_MOVED_TEMP = 302;
404c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
405c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
406c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 300: Multiple choices.
407c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
408c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_MULT_CHOICE = 300;
409c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
410c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
411c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 204: No content.
412c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
413c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_NO_CONTENT = 204;
414c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
415c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
416c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 406: Not acceptable.
417c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
418c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_NOT_ACCEPTABLE = 406;
419c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
420c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
421c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 203: Not authoritative.
422c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
423c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_NOT_AUTHORITATIVE = 203;
424c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
425c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
426c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 404: Not found.
427c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
428c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_NOT_FOUND = 404;
429c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
430c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
431c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 501: Not implemented.
432c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
433c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_NOT_IMPLEMENTED = 501;
434c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
435c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
436c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 304: Not modified.
437c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
438c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_NOT_MODIFIED = 304;
439c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
440c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
441c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 200: OK.
442c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
443c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_OK = 200;
444c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
445c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
446c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 206: Partial.
447c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
448c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_PARTIAL = 206;
449c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
450c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
451c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 402: Payment required.
452c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
453c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_PAYMENT_REQUIRED = 402;
454c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
455c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
456c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 412: Precondition failed.
457c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
458c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_PRECON_FAILED = 412;
459c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
460c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
461c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 407: Proxy authentication required.
462c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
463c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_PROXY_AUTH = 407;
464c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
465c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
466c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 414: Request too long.
467c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
468c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_REQ_TOO_LONG = 414;
469c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
470c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
471c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 205: Reset.
472c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
473c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_RESET = 205;
474c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
475c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
476c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 303: See other.
477c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
478c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_SEE_OTHER = 303;
479c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
480c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
481c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 500: Internal error.
482c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
483c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @deprecated Use {@link #HTTP_INTERNAL_ERROR}
484c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
485c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    @Deprecated
486c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_SERVER_ERROR = 500;
487c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
488c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
489c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 305: Use proxy.
490c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
491c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <p>Like Firefox and Chrome, this class doesn't honor this response code.
492c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Other implementations respond to this status code by retrying the request
493c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * using the HTTP proxy named by the response's Location header field.
494c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
495c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_USE_PROXY = 305;
496c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
497c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
498c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 401: Unauthorized.
499c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
500c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_UNAUTHORIZED = 401;
501c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
502c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
503c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 415: Unsupported type.
504c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
505c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_UNSUPPORTED_TYPE = 415;
506c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
507c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
508c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 503: Unavailable.
509c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
510c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_UNAVAILABLE = 503;
511c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
512c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
513c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Numeric status code, 505: Version not supported.
514c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
515c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static final int HTTP_VERSION = 505;
516c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
517c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
518c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns a new OkHttpConnection or OkHttpsConnection to {@code url}.
519c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
520c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static OkHttpConnection open(URL url) {
521c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        String protocol = url.getProtocol();
522c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (protocol.equals("http")) {
523c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return new libcore.net.http.HttpURLConnectionImpl(url, 80);
524c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        } else if (protocol.equals("https")) {
525c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return new libcore.net.http.HttpsURLConnectionImpl(url, 443);
526c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        } else {
527c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalArgumentException();
528c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
529c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
530c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
531c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
532c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns a new OkHttpConnection or OkHttpsConnection to {@code url} that
533c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * connects via {@code proxy}.
534c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
535c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static OkHttpConnection open(URL url, Proxy proxy) {
536c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        String protocol = url.getProtocol();
537c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (protocol.equals("http")) {
538c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return new libcore.net.http.HttpURLConnectionImpl(url, 80, proxy);
539c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        } else if (protocol.equals("https")) {
540c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return new libcore.net.http.HttpsURLConnectionImpl(url, 443, proxy);
541c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        } else {
542c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalArgumentException();
543c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
544c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
545c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
546c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
547c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Constructs a new {@code HttpURLConnection} instance pointing to the
548c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * resource specified by the {@code url}.
549c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
550c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param url
551c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            the URL of this connection.
552c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see java.net.URL
553c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see java.net.URLConnection
554c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
555c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    protected OkHttpConnection(URL url) {
556c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        super(url);
557c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
558c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
559c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
560c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Releases this connection so that its resources may be either reused or
561c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * closed.
562c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
563c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <p>Unlike other Java implementations, this will not necessarily close
564c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * socket connections that can be reused. You can disable all connection
565c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * reuse by setting the {@code http.keepAlive} system property to {@code
566c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * false} before issuing any HTTP requests.
567c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
568c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public abstract void disconnect();
569c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
570c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
571c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns an input stream from the server in the case of an error such as
572c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * the requested file has not been found on the remote server. This stream
573c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * can be used to read the data the server will send back.
574c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
575c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the error input stream returned by the server.
576c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
577c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public InputStream getErrorStream() {
578c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return null;
579c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
580c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
581c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
582c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the value of {@code followRedirects} which indicates if this
583c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * connection follows a different URL redirected by the server. It is
584c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * enabled by default.
585c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
586c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the value of the flag.
587c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #setFollowRedirects
588c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
589c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static boolean getFollowRedirects() {
590c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return followRedirects;
591c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
592c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
593c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
594c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the permission object (in this case {@code SocketPermission})
595c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * with the host and the port number as the target name and {@code
596c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * "resolve, connect"} as the action list. If the port number of this URL
597c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * instance is lower than {@code 0} the port will be set to {@code 80}.
598c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
599c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the permission object required for this connection.
600c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws java.io.IOException
601c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             if an IO exception occurs during the creation of the
602c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             permission object.
603c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
604c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    @Override
605c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public java.security.Permission getPermission() throws IOException {
606c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        int port = url.getPort();
607c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (port < 0) {
608c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            port = 80;
609c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
610c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return new SocketPermission(url.getHost() + ":" + port,
611c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath                "connect, resolve");
612c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
613c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
614c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
615c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the request method which will be used to make the request to the
616c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * remote HTTP server. All possible methods of this HTTP implementation is
617c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * listed in the class definition.
618c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
619c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the request method string.
620c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #method
621c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #setRequestMethod
622c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
623c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public String getRequestMethod() {
624c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return method;
625c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
626c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
627c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
628c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the response code returned by the remote HTTP server.
629c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
630c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the response code, -1 if no valid response code.
631c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws java.io.IOException
632c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             if there is an IO error during the retrieval.
633c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #getResponseMessage
634c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
635c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public int getResponseCode() throws IOException {
636c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        // Call getInputStream() first since getHeaderField() doesn't return
637c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        // exceptions
638c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        getInputStream();
639c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        String response = getHeaderField(0);
640c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (response == null) {
641c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return -1;
642c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
643c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        response = response.trim();
644c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        int mark = response.indexOf(" ") + 1;
645c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (mark == 0) {
646c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return -1;
647c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
648c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        int last = mark + 3;
649c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (last > response.length()) {
650c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            last = response.length();
651c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
652c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        responseCode = Integer.parseInt(response.substring(mark, last));
653c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (last + 1 <= response.length()) {
654c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            responseMessage = response.substring(last + 1);
655c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
656c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return responseCode;
657c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
658c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
659c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
660c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the response message returned by the remote HTTP server.
661c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
662c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the response message. {@code null} if no such response exists.
663c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws java.io.IOException
664c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             if there is an error during the retrieval.
665c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #getResponseCode()
666c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
667c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public String getResponseMessage() throws IOException {
668c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (responseMessage != null) {
669c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            return responseMessage;
670c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
671c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        getResponseCode();
672c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return responseMessage;
673c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
674c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
675c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
676c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Sets the flag of whether this connection will follow redirects returned
677c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * by the remote server.
678c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
679c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param auto
680c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            the value to enable or disable this option.
681c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
682c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public static void setFollowRedirects(boolean auto) {
683c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        followRedirects = auto;
684c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
685c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
686c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
687c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Sets the request command which will be sent to the remote HTTP server.
688c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * This method can only be called before the connection is made.
689c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
690c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param method
691c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            the string representing the method to be used.
692c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws java.net.ProtocolException
693c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             if this is called after connected, or the method is not
694c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             supported by this HTTP implementation.
695c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #getRequestMethod()
696c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #method
697c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
698c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public void setRequestMethod(String method) throws ProtocolException {
699c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (connected) {
700c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new ProtocolException("Connection already established");
701c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
702c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        for (String permittedUserMethod : PERMITTED_USER_METHODS) {
703c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            if (permittedUserMethod.equals(method)) {
704c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath                // if there is a supported method that matches the desired
705c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath                // method, then set the current method and return
706c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath                this.method = permittedUserMethod;
707c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath                return;
708c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            }
709c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
710c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        // if none matches, then throw ProtocolException
711c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        throw new ProtocolException("Unknown method '" + method + "'; must be one of "
712c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath                + Arrays.toString(PERMITTED_USER_METHODS));
713c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
714c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
715c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
716c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns whether this connection uses a proxy server or not.
717c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
718c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return {@code true} if this connection passes a proxy server, false
719c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *         otherwise.
720c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
721c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public abstract boolean usingProxy();
722c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
723c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
724c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the encoding used to transmit the response body over the network.
725c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * This is null or "identity" if the content was not encoded, or "gzip" if
726c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * the body was gzip compressed. Most callers will be more interested in the
727c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * {@link #getContentType() content type}, which may also include the
728c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * content's character encoding.
729c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
730c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    @Override public String getContentEncoding() {
731c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return super.getContentEncoding(); // overridden for Javadoc only
732c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
733c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
734c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
735c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns whether this connection follows redirects.
736c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
737c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return {@code true} if this connection follows redirects, false
738c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *         otherwise.
739c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
740c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public boolean getInstanceFollowRedirects() {
741c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return instanceFollowRedirects;
742c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
743c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
744c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
745c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Sets whether this connection follows redirects.
746c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
747c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param followRedirects
748c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            {@code true} if this connection will follows redirects, false
749c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            otherwise.
750c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
751c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public void setInstanceFollowRedirects(boolean followRedirects) {
752c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        instanceFollowRedirects = followRedirects;
753c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
754c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
755c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
756c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Returns the date value in milliseconds since {@code 01.01.1970, 00:00h}
757c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * corresponding to the header field {@code field}. The {@code defaultValue}
758c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * will be returned if no such field can be found in the response header.
759c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
760c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param field
761c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            the header field name.
762c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param defaultValue
763c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            the default value to use if the specified header field wont be
764c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            found.
765c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @return the header field represented in milliseconds since January 1,
766c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *         1970 GMT.
767c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
768c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    @Override
769c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public long getHeaderFieldDate(String field, long defaultValue) {
770c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        return super.getHeaderFieldDate(field, defaultValue);
771c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
772c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
773c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
774c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * If the length of a HTTP request body is known ahead, sets fixed length to
775c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * enable streaming without buffering. Sets after connection will cause an
776c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * exception.
777c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
778c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #setChunkedStreamingMode
779c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param contentLength
780c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *            the fixed length of the HTTP request body.
781c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws IllegalStateException
782c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             if already connected or another mode already set.
783c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws IllegalArgumentException
784c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *             if {@code contentLength} is less than zero.
785c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
786c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public void setFixedLengthStreamingMode(int contentLength) {
787c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (super.connected) {
788c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalStateException("Already connected");
789c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
790c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (chunkLength > 0) {
791c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalStateException("Already in chunked mode");
792c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
793c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (contentLength < 0) {
794c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalArgumentException("contentLength < 0");
795c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
796c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        this.fixedContentLength = contentLength;
797c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
798c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath
799c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    /**
800c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Stream a request body whose length is not known in advance. Old HTTP/1.0
801c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * only servers may not support this mode.
802c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
803c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * <p>When HTTP chunked encoding is used, the stream is divided into
804c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * chunks, each prefixed with a header containing the chunk's size. Setting
805c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * a large chunk length requires a large internal buffer, potentially
806c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * wasting memory. Setting a small chunk length increases the number of
807c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * bytes that must be transmitted because of the header on every chunk.
808c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * Most caller should use {@code 0} to get the system default.
809c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *
810c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @see #setFixedLengthStreamingMode
811c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @param chunkLength the length to use, or {@code 0} for the default chunk
812c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *     length.
813c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     * @throws IllegalStateException if already connected or another mode
814c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     *     already set.
815c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath     */
816c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    public void setChunkedStreamingMode(int chunkLength) {
817c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (super.connected) {
818c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalStateException("Already connected");
819c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
820c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (fixedContentLength >= 0) {
821c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            throw new IllegalStateException("Already in fixed-length mode");
822c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
823c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        if (chunkLength <= 0) {
824c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
825c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        } else {
826c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath            this.chunkLength = chunkLength;
827c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath        }
828c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath    }
829c3f6f16bd4a2338e88275641b9f2f56e816ca377Narayan Kamath}
830