Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient on Android : NoHttpResponseException through UMTS/3G

Tags:

android

http

I have got my android app that uses HttpClient to reach my servlet deployed on my Tomcat. It is installed on my HTC Magic.

If I launch it when connected on Wifi : it works. If I launch it when connected to 3G (GSM data network) : it doesn't work but my servlet is reached. In other word, it seems that my phone never get the response :

Technical problem while receiving response.
org.apache.http.NoHttpResponseException: The target server failed to respond
   at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:85)
   at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:174)
   at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:179)
   at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:235)
   at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:259)
   at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:279)
   at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:121)
   at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:410)
   at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
   at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
   at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)

If I use the web browser through 3G to activate the test HTML page that is packaged with my servlet, it reaches the same servlet with success (the page receives the response).

How could I debug HttpClient or ask it to dump everything ?

Does someone have a clue on what's going on ?

like image 438
Hubert Avatar asked Jan 12 '10 20:01

Hubert


3 Answers

I ran into this issue as well. It only occurred sporadically, usually on an initial http request. Subsequent requests would work fine. Adding setUseExpectContinue didn't seem to work.

The solution in my case was to add a retry handler that would retry the request on specific exceptions:

        HttpProtocolParams.setUseExpectContinue(client.getParams(), false);

        HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {

            public boolean retryRequest(IOException exception, int executionCount,
                    HttpContext context) {
                // retry a max of 5 times
                if(executionCount >= 5){
                    return false;
                }
                if(exception instanceof NoHttpResponseException){
                    return true;
                } else if (exception instanceof ClientProtocolException){
                    return true;
                } 
                return false;
            }
        };
        client.setHttpRequestRetryHandler(retryHandler);
like image 69
P. Taylor Goetz Avatar answered Nov 05 '22 21:11

P. Taylor Goetz


I finally got rid of this problem : simply a HTTP header that was badly handled by a squid server on the road :

Expect: 100-Continue

It seems to be there by default with DefaultHttpClient on android SDK. To tackle this, simply add that in your code :

  HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false);
like image 28
Hubert Avatar answered Nov 05 '22 19:11

Hubert


Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich)

http://code.google.com/p/android/issues/detail?id=13117 mentioned a work around which works on my phone.

like image 3
fishautumn Avatar answered Nov 05 '22 19:11

fishautumn