0

I'm using "com.loopj.android:android-async-http:1.4.5" in my Android app. The setup is that there is one instance of the below HttpDataSource class per API endpoint (eg: http://myhost.com/some/service/{pathParam}); thus there are multiple instances of AsyncHttpClient (and in turn Apache HttpClient); which might be causing my problems.

import java.io.IOException;
import java.net.URI;

import android.util.Log;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;

public class HttpDataSource {
  private final AsyncHttpClient asyncHttpClient;

  public HttpDataSource() {
    asyncHttpClient = new AsyncHttpClient();
    asyncHttpClient.setUserAgent(UserAgentFactory.createUserAgent());
    asyncHttpClient.setEnableRedirects(true);

    addRedirectListener();
  }

  protected void get(final String url, final RequestParams requestParams, final HttpResponseHandler responseHandler) {
    // Method not important; constructs headers for conditional GETs
    final Header[] headers = checkForMetaData(url);

    asyncHttpClient.get(null, url, headers, requestParams, new AsyncHttpResponseHandler() {
      @Override
      public void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBody) {
        // we do some work then pass on to the responseHandler
        responseHandler.onSuccess(statusCode, headers, responseBody);
      }

      @Override
      public void onFailure(final int statusCode, final Header[] headers, final byte[] responseBody,
          final Throwable error) {
        // we do some work then pass on to the responseHandler
        responseHandler.onFailure(statusCode, headers, responseBody, error);
      }
    });
  }

  private void addRedirectListener() {
    getHttpClient().addResponseInterceptor(new HttpResponseInterceptor() {
      @Override
      public void process(final HttpResponse httpResponse, final HttpContext httpContext)
          throws HttpException, IOException {
        if (httpResponse.getStatusLine().getStatusCode() == 302) {
          final URI reqUri = ((HttpUriRequest) httpContext.getAttribute(ExecutionContext.HTTP_REQUEST)).getURI();
          final HttpHost currentHost = (HttpHost) httpContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);

          final String url = (reqUri.isAbsolute()) ? reqUri.toString() : (currentHost.toURI() + reqUri.getPath());

          Log.e("HttpDataSource", "Got 302 for '" + url + "'");
        }
      }
    });
  }

  private DefaultHttpClient getHttpClient() {
    return ((DefaultHttpClient) asyncHttpClient.getHttpClient());
  }
}

When I make concurrent GETs to different URLs (eg: http://myhost.com/some/service/bar, http://myhost.com/some/service/foo) the redirect listener fires twice, but with the same HttpContext object, which is wrong I think. The logs are:

HttpDataSource﹕ Got 302 for 'http://myhost.com/some/service/foo'
HttpDataSource﹕ Got 302 for 'http://myhost.com/some/service/foo'

I suspect that the issue is with the Apache HttpClient, not Loop4J's AsyncHttpClient as the AsyncHttpClient has an instance of HttpClient which you would hope would be "instance safe".

How can I get the correct HttpContext object for a URL that returns a 302 when concurrent requests are being fired?

kierans
  • 2,034
  • 1
  • 16
  • 43

1 Answers1

-1
client.setEnableRedirects(true);
J0e3gan
  • 8,740
  • 10
  • 53
  • 80
Shuai Wang
  • 335
  • 1
  • 8
  • 20
  • There is no variable in the code listing called "client". In the HttpDataSource constructor, enable redirects is also enabled for the Apache HTTP Client instance. – kierans Oct 13 '15 at 04:46
  • `YourClinent.getClient().setEnableRedirects(true);` – Shuai Wang Oct 13 '15 at 09:12