19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 172269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornpackage android.net.http; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 197cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilsonimport com.android.internal.http.HttpDateTime; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.Header; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpEntity; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpEntityEnclosingRequest; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpException; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpHost; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpRequest; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpRequestInterceptor; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.HttpResponse; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.entity.AbstractHttpEntity; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.entity.ByteArrayEntity; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.client.HttpClient; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.client.ResponseHandler; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.client.ClientProtocolException; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.client.protocol.ClientContext; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.client.methods.HttpUriRequest; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.client.params.HttpClientParams; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.conn.ClientConnectionManager; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.conn.scheme.PlainSocketFactory; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.conn.scheme.Scheme; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.conn.scheme.SchemeRegistry; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.impl.client.DefaultHttpClient; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.impl.client.RequestWrapper; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.params.BasicHttpParams; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.params.HttpConnectionParams; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.params.HttpParams; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.params.HttpProtocolParams; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.protocol.BasicHttpProcessor; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.protocol.HttpContext; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.http.protocol.BasicHttpContext; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayOutputStream; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.zip.GZIPInputStream; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.zip.GZIPOutputStream; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.URI; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnorimport android.content.Context; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 6160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnorimport android.net.SSLCertificateSocketFactory; 6260586f2ec65d16d185767fce4311d3ed0e9112acDan Egnorimport android.net.SSLSessionCache; 637762d93621f508f4410fd37b5bbdfec0071b0420Paul Westbrookimport android.os.Looper; 647762d93621f508f4410fd37b5bbdfec0071b0420Paul Westbrookimport android.util.Log; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Subclass of the Apache {@link DefaultHttpClient} that is configured with 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reasonable default settings and registered schemes for Android, and 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * also lets the user add {@link HttpRequestInterceptor} classes. 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Don't create this directly, use the {@link #newInstance} factory method. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This client processes cookies but does not retain them by default. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To retain cookies, simply add a cookie store to the HttpContext:</p> 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);</pre> 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class AndroidHttpClient implements HttpClient { 7860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Gzip of data shorter than this probably won't be worthwhile 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static long DEFAULT_SYNC_MIN_GZIP_BYTES = 256; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "AndroidHttpClient"; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Interceptor throws an exception if the executing thread is blocked */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final HttpRequestInterceptor sThreadCheckInterceptor = 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HttpRequestInterceptor() { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void process(HttpRequest request, HttpContext context) { 897762d93621f508f4410fd37b5bbdfec0071b0420Paul Westbrook // Prevent the HttpRequest from being sent on the main thread 907762d93621f508f4410fd37b5bbdfec0071b0420Paul Westbrook if (Looper.myLooper() != null && Looper.myLooper() == Looper.getMainLooper() ) { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("This thread forbids HTTP requests"); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new HttpClient with reasonable defaults (which you can update). 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param userAgent to report in your HTTP requests 10060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor * @param context to use for caching SSL sessions (may be null for no caching) 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return AndroidHttpClient for you to use for all your requests. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor public static AndroidHttpClient newInstance(String userAgent, Context context) { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpParams params = new BasicHttpParams(); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Turn off stale checking. Our connections break all the time anyway, 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and it's not worth it to pay the penalty of checking every time. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpConnectionParams.setStaleCheckingEnabled(params, false); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Default connection and socket timeout of 20 seconds. Tweak to taste. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpConnectionParams.setConnectionTimeout(params, 20 * 1000); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpConnectionParams.setSoTimeout(params, 20 * 1000); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpConnectionParams.setSocketBufferSize(params, 8192); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't handle redirects -- return them to the caller. Our code 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // often wants to re-POST after a redirect, which we must do ourselves. 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpClientParams.setRedirecting(params, false); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11960586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor // Use a session cache for SSL sockets 12060586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor SSLSessionCache sessionCache = context == null ? null : new SSLSessionCache(context); 12160586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the specified user agent and register standard protocols. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpProtocolParams.setUserAgent(params, userAgent); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SchemeRegistry schemeRegistry = new SchemeRegistry(); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project schemeRegistry.register(new Scheme("http", 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PlainSocketFactory.getSocketFactory(), 80)); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project schemeRegistry.register(new Scheme("https", 12860586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor SSLCertificateSocketFactory.getHttpSocketFactory(30 * 1000, sessionCache), 443)); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientConnectionManager manager = 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ThreadSafeClientConnManager(params, schemeRegistry); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We use a factory method to modify superclass initialization 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // parameters without the funny call-a-static-method dance. 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AndroidHttpClient(manager, params); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new HttpClient with reasonable defaults (which you can update). 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param userAgent to report in your HTTP requests. 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return AndroidHttpClient for you to use for all your requests. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static AndroidHttpClient newInstance(String userAgent) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newInstance(userAgent, null /* session cache */); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HttpClient delegate; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private RuntimeException mLeakedException = new IllegalStateException( 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "AndroidHttpClient created and never closed"); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AndroidHttpClient(ClientConnectionManager ccm, HttpParams params) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.delegate = new DefaultHttpClient(ccm, params) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected BasicHttpProcessor createHttpProcessor() { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Add interceptor to prevent making requests from main thread. 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BasicHttpProcessor processor = super.createHttpProcessor(); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project processor.addRequestInterceptor(sThreadCheckInterceptor); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project processor.addRequestInterceptor(new CurlLogger()); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return processor; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected HttpContext createHttpContext() { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Same as DefaultHttpClient.createHttpContext() minus the 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cookie store. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpContext context = new BasicHttpContext(); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.setAttribute( 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientContext.AUTHSCHEME_REGISTRY, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getAuthSchemes()); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.setAttribute( 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientContext.COOKIESPEC_REGISTRY, 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getCookieSpecs()); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.setAttribute( 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientContext.CREDS_PROVIDER, 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getCredentialsProvider()); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return context; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLeakedException != null) { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Leak found", mLeakedException); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLeakedException = null; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Modifies a request to indicate to the server that we would like a 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * gzipped response. (Uses the "Accept-Encoding" HTTP header.) 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param request the request to modify 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #getUngzippedContent 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void modifyRequestToAcceptGzipResponse(HttpRequest request) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project request.addHeader("Accept-Encoding", "gzip"); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the input stream from a response entity. If the entity is gzipped 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then this will get a stream over the uncompressed data. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param entity the entity whose content should be read 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the input stream to read from 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IOException 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static InputStream getUngzippedContent(HttpEntity entity) 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream responseStream = entity.getContent(); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (responseStream == null) return responseStream; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Header header = entity.getContentEncoding(); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (header == null) return responseStream; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String contentEncoding = header.getValue(); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentEncoding == null) return responseStream; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentEncoding.contains("gzip")) responseStream 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new GZIPInputStream(responseStream); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return responseStream; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Release resources associated with this client. You must call this, 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or significant resources (sockets and memory) may be leaked. 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLeakedException != null) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getConnectionManager().shutdown(); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLeakedException = null; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HttpParams getParams() { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.getParams(); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ClientConnectionManager getConnectionManager() { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.getConnectionManager(); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HttpResponse execute(HttpUriRequest request) throws IOException { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(request); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HttpResponse execute(HttpUriRequest request, HttpContext context) 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(request, context); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HttpResponse execute(HttpHost target, HttpRequest request) 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(target, request); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public HttpResponse execute(HttpHost target, HttpRequest request, 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpContext context) throws IOException { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(target, request, context); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public <T> T execute(HttpUriRequest request, 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResponseHandler<? extends T> responseHandler) 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, ClientProtocolException { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(request, responseHandler); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public <T> T execute(HttpUriRequest request, 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResponseHandler<? extends T> responseHandler, HttpContext context) 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, ClientProtocolException { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(request, responseHandler, context); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public <T> T execute(HttpHost target, HttpRequest request, 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResponseHandler<? extends T> responseHandler) throws IOException, 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientProtocolException { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(target, request, responseHandler); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public <T> T execute(HttpHost target, HttpRequest request, 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResponseHandler<? extends T> responseHandler, HttpContext context) 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, ClientProtocolException { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return delegate.execute(target, request, responseHandler, context); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Compress data to send to server. 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a Http Entity holding the gzipped data. 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The data will not be compressed if it is too short. 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param data The bytes to compress 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Entity holding the data 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static AbstractHttpEntity getCompressedEntity(byte data[], ContentResolver resolver) 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AbstractHttpEntity entity; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data.length < getMinGzipSize(resolver)) { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entity = new ByteArrayEntity(data); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteArrayOutputStream arr = new ByteArrayOutputStream(); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OutputStream zipper = new GZIPOutputStream(arr); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipper.write(data); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zipper.close(); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entity = new ByteArrayEntity(arr.toByteArray()); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entity.setContentEncoding("gzip"); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return entity; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieves the minimum size for compressing data. 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shorter data will not be compressed. 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static long getMinGzipSize(ContentResolver resolver) { 31360586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor return DEFAULT_SYNC_MIN_GZIP_BYTES; // For now, this is just a constant. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* cURL logging support. */ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Logging tag and level. 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class LoggingConfiguration { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final String tag; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int level; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LoggingConfiguration(String tag, int level) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.tag = tag; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.level = level; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if logging is turned on for this configuration. 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isLoggable() { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Log.isLoggable(tag, level); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Prints a message using this configuration. 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void println(String message) { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.println(level, tag, message); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** cURL logging configuration. */ 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private volatile LoggingConfiguration curlConfiguration; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables cURL request logging for this client. 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name to log messages with 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param level at which to log messages (see {@link android.util.Log}) 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableCurlLogging(String name, int level) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name == null) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("name"); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (level < Log.VERBOSE || level > Log.ASSERT) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Level is out of range [" 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Log.VERBOSE + ".." + Log.ASSERT + "]"); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curlConfiguration = new LoggingConfiguration(name, level); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables cURL logging for this client. 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void disableCurlLogging() { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curlConfiguration = null; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Logs cURL commands equivalent to requests. 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class CurlLogger implements HttpRequestInterceptor { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void process(HttpRequest request, HttpContext context) 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws HttpException, IOException { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LoggingConfiguration configuration = curlConfiguration; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (configuration != null 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && configuration.isLoggable() 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && request instanceof HttpUriRequest) { 38460586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor // Never print auth token -- we used to check ro.secure=0 to 38560586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor // enable that, but can't do that in unbundled code. 38660586f2ec65d16d185767fce4311d3ed0e9112acDan Egnor configuration.println(toCurl((HttpUriRequest) request, false)); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Generates a cURL command equivalent to the given request. 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String toCurl(HttpUriRequest request, boolean logAuthToken) throws IOException { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringBuilder builder = new StringBuilder(); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append("curl "); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Header header: request.getAllHeaders()) { 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!logAuthToken 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (header.getName().equals("Authorization") || 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project header.getName().equals("Cookie"))) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append("--header \""); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(header.toString().trim()); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append("\" "); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project URI uri = request.getURI(); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is a wrapped request, use the URI from the original 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // request instead. getURI() on the wrapper seems to return a 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // relative URI. We want an absolute URI. 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (request instanceof RequestWrapper) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpRequest original = ((RequestWrapper) request).getOriginal(); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (original instanceof HttpUriRequest) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri = ((HttpUriRequest) original).getURI(); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append("\""); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(uri); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append("\""); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (request instanceof HttpEntityEnclosingRequest) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpEntityEnclosingRequest entityRequest = 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (HttpEntityEnclosingRequest) request; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HttpEntity entity = entityRequest.getEntity(); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entity != null && entity.isRepeatable()) { 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (entity.getContentLength() < 1024) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteArrayOutputStream stream = new ByteArrayOutputStream(); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project entity.writeTo(stream); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String entityString = stream.toString(); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Check the content type, too. 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(" --data-ascii \"") 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .append(entityString) 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .append("\""); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.append(" [TOO MUCH DATA TO INCLUDE]"); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return builder.toString(); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4487cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson 4497cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson /** 4507cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * Returns the date of the given HTTP date string. This method can identify 4517cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * and parse the date formats emitted by common HTTP servers, such as 4527cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * <a href="http://www.ietf.org/rfc/rfc0822.txt">RFC 822</a>, 4537cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * <a href="http://www.ietf.org/rfc/rfc0850.txt">RFC 850</a>, 4547cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * <a href="http://www.ietf.org/rfc/rfc1036.txt">RFC 1036</a>, 4557cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * <a href="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</a> and 4567cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * <a href="http://www.opengroup.org/onlinepubs/007908799/xsh/asctime.html">ANSI 4577cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * C's asctime()</a>. 4587cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * 4597cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * @return the number of milliseconds since Jan. 1, 1970, midnight GMT. 4607cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * @throws IllegalArgumentException if {@code dateString} is not a date or 4617cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson * of an unsupported format. 4627cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson */ 4637cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson public static long parseDate(String dateString) { 4647cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson return HttpDateTime.parse(dateString); 4657cfa90fee54f44831ac492891d1c123601c2a262Jesse Wilson } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 467