FileDocCategorySizeDatePackage
AndroidHttpClient.javaAPI DocAndroid 1.5 API19300Wed May 06 22:41:54 BST 2009android.net.http

AndroidHttpClient

public final class AndroidHttpClient extends Object implements HttpClient
Subclass of the Apache {@link DefaultHttpClient} that is configured with reasonable default settings and registered schemes for Android, and also lets the user add {@link HttpRequestInterceptor} classes. Don't create this directly, use the {@link #newInstance} factory method.

This client processes cookies but does not retain them by default. To retain cookies, simply add a cookie store to the HttpContext:

context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
{@hide}

Fields Summary
public static long
DEFAULT_SYNC_MIN_GZIP_BYTES
private static final String
TAG
private static final ThreadLocal
sThreadBlocked
Set if HTTP requests are blocked from being executed on this thread
private static final HttpRequestInterceptor
sThreadCheckInterceptor
Interceptor throws an exception if the executing thread is blocked
private final HttpClient
delegate
private RuntimeException
mLeakedException
private volatile LoggingConfiguration
curlConfiguration
cURL logging configuration.
Constructors Summary
private AndroidHttpClient(ClientConnectionManager ccm, HttpParams params)


         
        this.delegate = new DefaultHttpClient(ccm, params) {
            @Override
            protected BasicHttpProcessor createHttpProcessor() {
                // Add interceptor to prevent making requests from main thread.
                BasicHttpProcessor processor = super.createHttpProcessor();
                processor.addRequestInterceptor(sThreadCheckInterceptor);
                processor.addRequestInterceptor(new CurlLogger());

                return processor;
            }

            @Override
            protected HttpContext createHttpContext() {
                // Same as DefaultHttpClient.createHttpContext() minus the
                // cookie store.
                HttpContext context = new BasicHttpContext();
                context.setAttribute(
                        ClientContext.AUTHSCHEME_REGISTRY,
                        getAuthSchemes());
                context.setAttribute(
                        ClientContext.COOKIESPEC_REGISTRY,
                        getCookieSpecs());
                context.setAttribute(
                        ClientContext.CREDS_PROVIDER,
                        getCredentialsProvider());
                return context;
            }
        };
    
Methods Summary
public voidclose()
Release resources associated with this client. You must call this, or significant resources (sockets and memory) may be leaked.

        if (mLeakedException != null) {
            getConnectionManager().shutdown();
            mLeakedException = null;
        }
    
public voiddisableCurlLogging()
Disables cURL logging for this client.

        curlConfiguration = null;
    
public voidenableCurlLogging(java.lang.String name, int level)
Enables cURL request logging for this client.

param
name to log messages with
param
level at which to log messages (see {@link android.util.Log})

        if (name == null) {
            throw new NullPointerException("name");
        }
        if (level < Log.VERBOSE || level > Log.ASSERT) {
            throw new IllegalArgumentException("Level is out of range ["
                + Log.VERBOSE + ".." + Log.ASSERT + "]");    
        }

        curlConfiguration = new LoggingConfiguration(name, level);
    
public org.apache.http.HttpResponseexecute(org.apache.http.client.methods.HttpUriRequest request)

        return delegate.execute(request);
    
public org.apache.http.HttpResponseexecute(org.apache.http.client.methods.HttpUriRequest request, org.apache.http.protocol.HttpContext context)

        return delegate.execute(request, context);
    
public org.apache.http.HttpResponseexecute(org.apache.http.HttpHost target, org.apache.http.HttpRequest request)

        return delegate.execute(target, request);
    
public org.apache.http.HttpResponseexecute(org.apache.http.HttpHost target, org.apache.http.HttpRequest request, org.apache.http.protocol.HttpContext context)

        return delegate.execute(target, request, context);
    
public Texecute(org.apache.http.client.methods.HttpUriRequest request, org.apache.http.client.ResponseHandler responseHandler)

        return delegate.execute(request, responseHandler);
    
public Texecute(org.apache.http.client.methods.HttpUriRequest request, org.apache.http.client.ResponseHandler responseHandler, org.apache.http.protocol.HttpContext context)

        return delegate.execute(request, responseHandler, context);
    
public Texecute(org.apache.http.HttpHost target, org.apache.http.HttpRequest request, org.apache.http.client.ResponseHandler responseHandler)

        return delegate.execute(target, request, responseHandler);
    
public Texecute(org.apache.http.HttpHost target, org.apache.http.HttpRequest request, org.apache.http.client.ResponseHandler responseHandler, org.apache.http.protocol.HttpContext context)

        return delegate.execute(target, request, responseHandler, context);
    
protected voidfinalize()

        super.finalize();
        if (mLeakedException != null) {
            Log.e(TAG, "Leak found", mLeakedException);
            mLeakedException = null;
        }
    
public static org.apache.http.entity.AbstractHttpEntitygetCompressedEntity(byte[] data, android.content.ContentResolver resolver)
Compress data to send to server. Creates a Http Entity holding the gzipped data. The data will not be compressed if it is too short.

param
data The bytes to compress
return
Entity holding the data

        AbstractHttpEntity entity;
        if (data.length < getMinGzipSize(resolver)) {
            entity = new ByteArrayEntity(data);
        } else {
            ByteArrayOutputStream arr = new ByteArrayOutputStream();
            OutputStream zipper = new GZIPOutputStream(arr);
            zipper.write(data);
            zipper.close();
            entity = new ByteArrayEntity(arr.toByteArray());
            entity.setContentEncoding("gzip");
        }
        return entity;
    
public org.apache.http.conn.ClientConnectionManagergetConnectionManager()

        return delegate.getConnectionManager();
    
public static longgetMinGzipSize(android.content.ContentResolver resolver)
Retrieves the minimum size for compressing data. Shorter data will not be compressed.

        String sMinGzipBytes = Settings.Gservices.getString(resolver,
                Settings.Gservices.SYNC_MIN_GZIP_BYTES);

        if (!TextUtils.isEmpty(sMinGzipBytes)) {
            try {
                return Long.parseLong(sMinGzipBytes);
            } catch (NumberFormatException nfe) {
                Log.w(TAG, "Unable to parse " +
                        Settings.Gservices.SYNC_MIN_GZIP_BYTES + " " +
                        sMinGzipBytes, nfe);
            }
        }
        return DEFAULT_SYNC_MIN_GZIP_BYTES;
    
public org.apache.http.params.HttpParamsgetParams()

        return delegate.getParams();
    
public static java.io.InputStreamgetUngzippedContent(org.apache.http.HttpEntity entity)
Gets the input stream from a response entity. If the entity is gzipped then this will get a stream over the uncompressed data.

param
entity the entity whose content should be read
return
the input stream to read from
throws
IOException

        InputStream responseStream = entity.getContent();
        if (responseStream == null) return responseStream;
        Header header = entity.getContentEncoding();
        if (header == null) return responseStream;
        String contentEncoding = header.getValue();
        if (contentEncoding == null) return responseStream;
        if (contentEncoding.contains("gzip")) responseStream
                = new GZIPInputStream(responseStream);
        return responseStream;
    
public static voidmodifyRequestToAcceptGzipResponse(org.apache.http.HttpRequest request)
Modifies a request to indicate to the server that we would like a gzipped response. (Uses the "Accept-Encoding" HTTP header.)

param
request the request to modify
see
#getUngzippedContent

        request.addHeader("Accept-Encoding", "gzip");
    
public static android.net.http.AndroidHttpClientnewInstance(java.lang.String userAgent, org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache sessionCache)
Create a new HttpClient with reasonable defaults (which you can update).

param
userAgent to report in your HTTP requests.
param
sessionCache persistent session cache
return
AndroidHttpClient for you to use for all your requests.


                                           
        
              
        HttpParams params = new BasicHttpParams();

        // Turn off stale checking.  Our connections break all the time anyway,
        // and it's not worth it to pay the penalty of checking every time.
        HttpConnectionParams.setStaleCheckingEnabled(params, false);

        // Default connection and socket timeout of 20 seconds.  Tweak to taste.
        HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
        HttpConnectionParams.setSoTimeout(params, 20 * 1000);
        HttpConnectionParams.setSocketBufferSize(params, 8192);

        // Don't handle redirects -- return them to the caller.  Our code
        // often wants to re-POST after a redirect, which we must do ourselves.
        HttpClientParams.setRedirecting(params, false);

        // Set the specified user agent and register standard protocols.
        HttpProtocolParams.setUserAgent(params, userAgent);
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http",
                PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https",
                socketFactoryWithCache(sessionCache), 443));

        ClientConnectionManager manager =
                new ThreadSafeClientConnManager(params, schemeRegistry);

        // We use a factory method to modify superclass initialization
        // parameters without the funny call-a-static-method dance.
        return new AndroidHttpClient(manager, params);
    
public static android.net.http.AndroidHttpClientnewInstance(java.lang.String userAgent)
Create a new HttpClient with reasonable defaults (which you can update).

param
userAgent to report in your HTTP requests.
return
AndroidHttpClient for you to use for all your requests.

        return newInstance(userAgent, null /* session cache */);
    
public static voidsetThreadBlocked(boolean blocked)
Block this thread from executing HTTP requests. Used to guard against HTTP requests blocking the main application thread.

param
blocked if HTTP requests run on this thread should be denied

        sThreadBlocked.set(blocked);
    
private static org.apache.http.conn.ssl.SSLSocketFactorysocketFactoryWithCache(org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache sessionCache)
Returns a socket factory backed by the given persistent session cache.

param
sessionCache to retrieve sessions from, null for no cache

        if (sessionCache == null) {
            // Use the default factory which doesn't support persistent
            // caching.
            return SSLSocketFactory.getSocketFactory();
        }

        // Create a new SSL context backed by the cache.
        // TODO: Keep a weak *identity* hash map of caches to engines. In the
        // mean time, if we have two engines for the same cache, they'll still
        // share sessions but will have to do so through the persistent cache.
        SSLContextImpl sslContext = new SSLContextImpl();
        try {
            sslContext.engineInit(null, null, null, sessionCache, null);
        } catch (KeyManagementException e) {
            throw new AssertionError(e);
        }
        return new SSLSocketFactory(sslContext.engineGetSocketFactory());
    
private static java.lang.StringtoCurl(org.apache.http.client.methods.HttpUriRequest request, boolean logAuthToken)
Generates a cURL command equivalent to the given request.

        StringBuilder builder = new StringBuilder();

        builder.append("curl ");

        for (Header header: request.getAllHeaders()) {
            if (!logAuthToken
                    && (header.getName().equals("Authorization") ||
                        header.getName().equals("Cookie"))) {
                continue;
            }
            builder.append("--header \"");
            builder.append(header.toString().trim());
            builder.append("\" ");
        }

        URI uri = request.getURI();

        // If this is a wrapped request, use the URI from the original
        // request instead. getURI() on the wrapper seems to return a
        // relative URI. We want an absolute URI.
        if (request instanceof RequestWrapper) {
            HttpRequest original = ((RequestWrapper) request).getOriginal();
            if (original instanceof HttpUriRequest) {
                uri = ((HttpUriRequest) original).getURI();
            }
        }

        builder.append("\"");
        builder.append(uri);
        builder.append("\"");

        if (request instanceof HttpEntityEnclosingRequest) {
            HttpEntityEnclosingRequest entityRequest =
                    (HttpEntityEnclosingRequest) request;
            HttpEntity entity = entityRequest.getEntity();
            if (entity != null && entity.isRepeatable()) {
                if (entity.getContentLength() < 1024) {
                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    entity.writeTo(stream);
                    String entityString = stream.toString();

                    // TODO: Check the content type, too.
                    builder.append(" --data-ascii \"")
                            .append(entityString)
                            .append("\"");
                } else {
                    builder.append(" [TOO MUCH DATA TO INCLUDE]");
                }
            }
        }

        return builder.toString();