Android Open Source - droid-fu Better Http Request Base






From Project

Back to project page droid-fu.

License

The source code is released under:

Apache License

If you think the Android project droid-fu listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/* Copyright (c) 2009 Matthias Kaeppler
 *//w ww. j  a va 2 s. c  o m
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.droidfu.http;

import java.io.IOException;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

import android.util.Log;

import com.github.droidfu.cachefu.HttpResponseCache;
import com.github.droidfu.http.CachedHttpResponse.ResponseData;

public abstract class BetterHttpRequestBase implements BetterHttpRequest,
        ResponseHandler<BetterHttpResponse> {

    private static final int MAX_RETRIES = 5;

    protected static final String HTTP_CONTENT_TYPE_HEADER = "Content-Type";

    protected List<Integer> expectedStatusCodes = new ArrayList<Integer>();

    protected AbstractHttpClient httpClient;

    protected HttpUriRequest request;

    protected int maxRetries = MAX_RETRIES;

    private int oldTimeout; // used to cache the global timeout when changing it for one request

    private int executionCount;

    BetterHttpRequestBase(AbstractHttpClient httpClient) {
        this.httpClient = httpClient;
    }

    public HttpUriRequest unwrap() {
        return request;
    }

    public String getRequestUrl() {
        return request.getURI().toString();
    }

    public BetterHttpRequestBase expecting(Integer... statusCodes) {
        expectedStatusCodes = Arrays.asList(statusCodes);
        return this;
    }

    public BetterHttpRequestBase retries(int retries) {
        if (retries < 0) {
            this.maxRetries = 0;
        } else if (retries > MAX_RETRIES) {
            this.maxRetries = MAX_RETRIES;
        } else {
            this.maxRetries = retries;
        }
        return this;
    }

    public BetterHttpRequest withTimeout(int timeout) {
        oldTimeout = httpClient.getParams().getIntParameter(CoreConnectionPNames.SO_TIMEOUT,
                BetterHttp.DEFAULT_SOCKET_TIMEOUT);
        BetterHttp.setSocketTimeout(timeout);
        return this;
    }

    public BetterHttpResponse send() throws ConnectException {

        BetterHttpRequestRetryHandler retryHandler = new BetterHttpRequestRetryHandler(maxRetries);

        // tell HttpClient to user our own retry handler
        httpClient.setHttpRequestRetryHandler(retryHandler);

        HttpContext context = new BasicHttpContext();

        // Grab a coffee now and lean back, I'm not good at explaining stuff. This code realizes
        // a second retry layer on top of HttpClient. Rationale: HttpClient.execute sometimes craps
        // out even *before* the HttpRequestRetryHandler set above is called, e.g. on a
        // "Network unreachable" SocketException, which can happen when failing over from Wi-Fi to
        // 3G or vice versa. Hence, we catch these exceptions, feed it through the same retry
        // decision method *again*, and align the execution count along the way.
        boolean retry = true;
        IOException cause = null;
        while (retry) {
            try {
                return httpClient.execute(request, this, context);
            } catch (IOException e) {
                cause = e;
                retry = retryRequest(retryHandler, cause, context);
            } catch (NullPointerException e) {
                // there's a bug in HttpClient 4.0.x that on some occasions causes
                // DefaultRequestExecutor to throw an NPE, see
                // http://code.google.com/p/android/issues/detail?id=5255
                cause = new IOException("NPE in HttpClient" + e.getMessage());
                retry = retryRequest(retryHandler, cause, context);
            } finally {
                // if timeout was changed with this request using withTimeout(), reset it
                if (oldTimeout != BetterHttp.getSocketTimeout()) {
                    BetterHttp.setSocketTimeout(oldTimeout);
                }
            }
        }

        // no retries left, crap out with exception
        ConnectException ex = new ConnectException();
        ex.initCause(cause);
        throw ex;
    }

    private boolean retryRequest(BetterHttpRequestRetryHandler retryHandler, IOException cause,
            HttpContext context) {
        Log.e(BetterHttp.LOG_TAG, "Intercepting exception that wasn't handled by HttpClient");
        executionCount = Math.max(executionCount, retryHandler.getTimesRetried());
        return retryHandler.retryRequest(cause, ++executionCount, context);
    }

    public BetterHttpResponse handleResponse(HttpResponse response) throws IOException {
        int status = response.getStatusLine().getStatusCode();
        if (expectedStatusCodes != null && !expectedStatusCodes.isEmpty()
                && !expectedStatusCodes.contains(status)) {
            throw new HttpResponseException(status, "Unexpected status code: " + status);
        }

        BetterHttpResponse bhttpr = new BetterHttpResponseImpl(response);
        HttpResponseCache responseCache = BetterHttp.getResponseCache();
        if (responseCache != null) {
            ResponseData responseData = new ResponseData(status, bhttpr.getResponseBodyAsBytes());
            responseCache.put(getRequestUrl(), responseData);
        }
        return bhttpr;
    }
}




Java Source Code List

com.github.droidfu.DroidFuApplication.java
com.github.droidfu.DroidFu.java
com.github.droidfu.activities.BetterActivityHelper.java
com.github.droidfu.activities.BetterActivity.java
com.github.droidfu.activities.BetterDefaultActivity.java
com.github.droidfu.activities.BetterExpandableListActivity.java
com.github.droidfu.activities.BetterListActivity.java
com.github.droidfu.activities.BetterMapActivity.java
com.github.droidfu.activities.BetterPreferenceActivity.java
com.github.droidfu.adapters.ListAdapterWithProgress.java
com.github.droidfu.adapters.WebGalleryAdapter.java
com.github.droidfu.cachefu.AbstractCache.java
com.github.droidfu.cachefu.CacheHelper.java
com.github.droidfu.cachefu.CachedList.java
com.github.droidfu.cachefu.CachedModel.java
com.github.droidfu.cachefu.HttpResponseCache.java
com.github.droidfu.cachefu.ImageCache.java
com.github.droidfu.cachefu.ModelCache.java
com.github.droidfu.concurrent.BetterAsyncTaskCallable.java
com.github.droidfu.concurrent.BetterAsyncTask.java
com.github.droidfu.dialogs.DialogClickListener.java
com.github.droidfu.exception.ResourceMessageException.java
com.github.droidfu.http.BetterHttpRequestBase.java
com.github.droidfu.http.BetterHttpRequestRetryHandler.java
com.github.droidfu.http.BetterHttpRequest.java
com.github.droidfu.http.BetterHttpResponseImpl.java
com.github.droidfu.http.BetterHttpResponse.java
com.github.droidfu.http.BetterHttp.java
com.github.droidfu.http.CachedHttpRequest.java
com.github.droidfu.http.CachedHttpResponse.java
com.github.droidfu.http.ConnectionChangedBroadcastReceiver.java
com.github.droidfu.http.HttpDelete.java
com.github.droidfu.http.HttpGet.java
com.github.droidfu.http.HttpPost.java
com.github.droidfu.http.HttpPut.java
com.github.droidfu.http.ssl.EasySSLSocketFactory.java
com.github.droidfu.http.ssl.TrivialTrustManager.java
com.github.droidfu.imageloader.ImageLoaderHandler.java
com.github.droidfu.imageloader.ImageLoader.java
com.github.droidfu.listeners.MapGestureListener.java
com.github.droidfu.services.BetterService.java
com.github.droidfu.support.ArraySupport.java
com.github.droidfu.support.DiagnosticSupport.java
com.github.droidfu.support.DisplaySupport.java
com.github.droidfu.support.IntentSupport.java
com.github.droidfu.support.StringSupport.java
com.github.droidfu.testsupport.DroidFuAssertions.java
com.github.droidfu.widgets.WebImageView.java
com.google.common.base.FinalizableReferenceQueue.java
com.google.common.base.FinalizableReference.java
com.google.common.base.FinalizableSoftReference.java
com.google.common.base.FinalizableWeakReference.java
com.google.common.base.Function.java
com.google.common.base.Objects.java
com.google.common.base.internal.Finalizer.java
com.google.common.collect.AbstractMapEntry.java
com.google.common.collect.AsynchronousComputationException.java
com.google.common.collect.ComputationException.java
com.google.common.collect.CustomConcurrentHashMap.java
com.google.common.collect.ExpirationTimer.java
com.google.common.collect.MapMaker.java
com.google.common.collect.NullOutputException.java