1d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/* 2d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project 3d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 4d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License"); 5d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * you may not use this file except in compliance with the License. 6d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * You may obtain a copy of the License at 7d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 8d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * http://www.apache.org/licenses/LICENSE-2.0 9d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * 10d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software 11d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS, 12d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * See the License for the specific language governing permissions and 14d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * limitations under the License. 15d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 16d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 17d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupackage com.android.volley.toolbox; 18d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 19d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.AuthFailureError; 20d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.Request; 21e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queruimport com.android.volley.Request.Method; 22d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 23d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.Header; 24d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.HttpEntity; 25d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.HttpResponse; 26d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.ProtocolVersion; 27d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.StatusLine; 28d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.entity.BasicHttpEntity; 29d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.message.BasicHeader; 30d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.message.BasicHttpResponse; 31d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport org.apache.http.message.BasicStatusLine; 32d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 33d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.io.DataOutputStream; 34d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.io.IOException; 35d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.io.InputStream; 36d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.net.HttpURLConnection; 37d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.net.URL; 38d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.HashMap; 39d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.List; 40d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Map; 41d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Map.Entry; 42d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 433f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrillimport javax.net.ssl.HttpsURLConnection; 443f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrillimport javax.net.ssl.SSLSocketFactory; 453f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill 46d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/** 47d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * An {@link HttpStack} based on {@link HttpURLConnection}. 48d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 49d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupublic class HurlStack implements HttpStack { 50d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 51e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private static final String HEADER_CONTENT_TYPE = "Content-Type"; 52e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 53d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 54d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * An interface for transforming URLs before use. 55d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 56d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public interface UrlRewriter { 57d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 58d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Returns a URL to use instead of the provided one, or null to indicate 59d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * this URL should not be used at all. 60d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 61d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public String rewriteUrl(String originalUrl); 62d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 63d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 64d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final UrlRewriter mUrlRewriter; 653f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill private final SSLSocketFactory mSslSocketFactory; 66d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 67d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public HurlStack() { 68d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru this(null); 69d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 70d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 71d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 72d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param urlRewriter Rewriter to use for request URLs 73d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 74d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public HurlStack(UrlRewriter urlRewriter) { 753f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill this(urlRewriter, null); 763f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill } 773f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill 783f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill /** 793f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill * @param urlRewriter Rewriter to use for request URLs 803f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill * @param sslSocketFactory SSL factory to use for HTTPS connections 813f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill */ 823f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill public HurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) { 83d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mUrlRewriter = urlRewriter; 843f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill mSslSocketFactory = sslSocketFactory; 85d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 86d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 87d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 88d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) 89d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru throws IOException, AuthFailureError { 90d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru String url = request.getUrl(); 91d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru HashMap<String, String> map = new HashMap<String, String>(); 92d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru map.putAll(request.getHeaders()); 93d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru map.putAll(additionalHeaders); 94d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (mUrlRewriter != null) { 95d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru String rewritten = mUrlRewriter.rewriteUrl(url); 96d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (rewritten == null) { 97d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru throw new IOException("URL blocked by rewriter: " + url); 98d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 99d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru url = rewritten; 100d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 101d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru URL parsedUrl = new URL(url); 102d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru HttpURLConnection connection = openConnection(parsedUrl, request); 103d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (String headerName : map.keySet()) { 104d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru connection.addRequestProperty(headerName, map.get(headerName)); 105d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 106e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru setConnectionParametersForRequest(connection, request); 107d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Initialize HttpResponse with data from the HttpURLConnection. 108d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1); 109d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru int responseCode = connection.getResponseCode(); 110d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (responseCode == -1) { 111d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // -1 is returned by getResponseCode() if the response code could not be retrieved. 112d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Signal to the caller that something was wrong with the connection. 113d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru throw new IOException("Could not retrieve response code from HttpUrlConnection."); 114d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 115d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru StatusLine responseStatus = new BasicStatusLine(protocolVersion, 116d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru connection.getResponseCode(), connection.getResponseMessage()); 117d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru BasicHttpResponse response = new BasicHttpResponse(responseStatus); 118d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru response.setEntity(entityFromConnection(connection)); 119d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) { 120d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (header.getKey() != null) { 121d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru Header h = new BasicHeader(header.getKey(), header.getValue().get(0)); 122d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru response.addHeader(h); 123d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 124d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 125d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return response; 126d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 127d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 128d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 129d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Initializes an {@link HttpEntity} from the given {@link HttpURLConnection}. 130d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param connection 131d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @return an HttpEntity populated with data from <code>connection</code>. 132d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 133d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private static HttpEntity entityFromConnection(HttpURLConnection connection) { 134d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru BasicHttpEntity entity = new BasicHttpEntity(); 135d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru InputStream inputStream; 136d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru try { 137d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru inputStream = connection.getInputStream(); 138d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } catch (IOException ioe) { 139d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru inputStream = connection.getErrorStream(); 140d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 141d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru entity.setContent(inputStream); 142d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru entity.setContentLength(connection.getContentLength()); 143d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru entity.setContentEncoding(connection.getContentEncoding()); 144d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru entity.setContentType(connection.getContentType()); 145d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return entity; 146d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 147d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 148d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru /** 14905a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton * Create an {@link HttpURLConnection} for the specified {@code url}. 15005a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton */ 15105a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton protected HttpURLConnection createConnection(URL url) throws IOException { 15205a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton return (HttpURLConnection) url.openConnection(); 15305a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton } 15405a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton 15505a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton /** 156d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Opens an {@link HttpURLConnection} with parameters. 157d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @param url 158d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @return an open connection 159d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * @throws IOException 160d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */ 161d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private HttpURLConnection openConnection(URL url, Request<?> request) throws IOException { 16205a1b0edb25ed84c95523df7a81bd87a44b697d7Jake Wharton HttpURLConnection connection = createConnection(url); 163d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 164d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru int timeoutMs = request.getTimeoutMs(); 165d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru connection.setConnectTimeout(timeoutMs); 166d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru connection.setReadTimeout(timeoutMs); 167d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru connection.setUseCaches(false); 168d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru connection.setDoInput(true); 1693f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill 1703f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill // use caller-provided custom SslSocketFactory, if any, for HTTPS 1713f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) { 1723f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory); 1733f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill } 1743f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill 175d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return connection; 176d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 177d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 178e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru @SuppressWarnings("deprecation") 179e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru /* package */ static void setConnectionParametersForRequest(HttpURLConnection connection, 180e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru Request<?> request) throws IOException, AuthFailureError { 181e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru switch (request.getMethod()) { 182e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru case Method.DEPRECATED_GET_OR_POST: 183e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // This is the deprecated way that needs to be handled for backwards compatibility. 184e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // If the request's post body is null, then the assumption is that the request is 185e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // GET. Otherwise, it is assumed that the request is a POST. 186e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru byte[] postBody = request.getPostBody(); 187e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru if (postBody != null) { 188e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // Prepare output. There is no need to set Content-Length explicitly, 189e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // since this is handled by HttpURLConnection using the size of the prepared 190e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // output stream. 191e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setDoOutput(true); 192e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setRequestMethod("POST"); 193e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.addRequestProperty(HEADER_CONTENT_TYPE, 194e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru request.getPostBodyContentType()); 195e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru DataOutputStream out = new DataOutputStream(connection.getOutputStream()); 196e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru out.write(postBody); 197e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru out.close(); 198e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 199e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru break; 200e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru case Method.GET: 201e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // Not necessary to set the request method because connection defaults to GET but 202e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru // being explicit here. 203e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setRequestMethod("GET"); 204e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru break; 205e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru case Method.DELETE: 206e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setRequestMethod("DELETE"); 207e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru break; 208e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru case Method.POST: 209e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setRequestMethod("POST"); 2103f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill addBodyIfExists(connection, request); 211e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru break; 212e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru case Method.PUT: 213e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setRequestMethod("PUT"); 2143f081a83d5ed92d4e6ec4abf87137cb246d92d0cDan Morrill addBodyIfExists(connection, request); 215e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru break; 216364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu case Method.HEAD: 217364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu connection.setRequestMethod("HEAD"); 218364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu break; 219364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu case Method.OPTIONS: 220364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu connection.setRequestMethod("OPTIONS"); 221364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu break; 222364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu case Method.TRACE: 223364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu connection.setRequestMethod("TRACE"); 224364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu break; 225364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu case Method.PATCH: 226364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu connection.setRequestMethod("PATCH"); 227e7cdf98078bc94a2e430d9edef7e9b01250765acMiguel A. Martin addBodyIfExists(connection, request); 228364614be46d20fba35c3b6bc1c2d43fe8e861e9cMaurice Chu break; 229e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru default: 230e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru throw new IllegalStateException("Unknown method type."); 231e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 232e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 233e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru 234e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru private static void addBodyIfExists(HttpURLConnection connection, Request<?> request) 235d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru throws IOException, AuthFailureError { 236e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru byte[] body = request.getBody(); 237e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru if (body != null) { 238e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.setDoOutput(true); 239e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType()); 240e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru DataOutputStream out = new DataOutputStream(connection.getOutputStream()); 241e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru out.write(body); 242e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru out.close(); 243e48f4430bfd3030350aa5ba827b449c37e2fadc9Jean-Baptiste Queru } 244d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 245d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru} 246