Michael B.
Michael B.

Reputation: 3430

Https connection Android

I have an applications that connects to a web service that uses an Entrust valid certificate. The only difference is that it's a wildcard SSL.

The problem is : I get an

ERROR/NoHttpResponseException(5195): org.apache.http.NoHttpResponseException: The target server failed to respond

when I'm on 3G. When on WIFI it works, on simulator it works, tethering the simulator trough my phones 3G works. But the app on my phone from 3G dosen't work at all. Tested on a HTC Legend CM7.0.3(2.3.3) and Nexus S 2.3.3 on 2 different network(Virgin Mobile Canada and Fido).

I have a PCAP dump from my device that show some error, but I don't understand it really well.

Acknowledgement number: Broken TCP. The acknowledge field is nonzero while the ACK flag is not set

I tried the fix on this question this question too. I don't know where else to go.

By the way, the web service work with the browser on 3G.

We are also using basic auth with HttpRequestInterceptor.

I think this is all the details I can give. If something else is needed feel free to ask.

This question is related too, I've tried both fix, none of them work.

Edit

I'm starting to think that this could be better suited for serverfault.com

This is the dump file and the screenshot

PCAP

Edit 2

This is the code I'm using to connect to the web service in question.

protected HttpEntity sendData(List<NameValuePair> pairs, String method)
            throws ClientProtocolException, IOException,
            AuthenticationException {

        pairs.add(new BasicNameValuePair(KEY_SECURITY, KEY));
        pairs.add(new BasicNameValuePair(LANG_KEY, lang));
        pairs.add(new BasicNameValuePair(OS_KEY, OS));
        pairs.add(new BasicNameValuePair(MODEL_KEY, model));
        pairs.add(new BasicNameValuePair(CARRIER_KEY, carrier));

        DefaultHttpClient client = getClient();

        HttpPost post = new HttpPost();
        try {
            post.setHeader("Content-Type", "application/x-www-form-urlencoded");
            post.setEntity(new UrlEncodedFormEntity(pairs));
        } catch (UnsupportedEncodingException e1) {
            Log.e("UnsupportedEncodingException", e1.toString());
        }

        URI uri = URI.create(method);

        post.setURI(uri);

        client.addRequestInterceptor(preemptiveAuth, 0);

        HttpHost target = new HttpHost(host, port, protocol);
        HttpContext httpContext = new BasicHttpContext();

        HttpResponse response = client.execute(target, post, httpContext);
        int statusCode = response.getStatusLine().getStatusCode();

        if (statusCode == 401) {
            throw new AuthenticationException("Invalid username or password");
        }

        return response.getEntity();
    }

Upvotes: 4

Views: 7954

Answers (3)

Michael B.
Michael B.

Reputation: 3430

We finally found the problem. It wasn't code related.

It was the reverse DNS that was timing-out. Because I dind't receive any answer from the reverse DNS my apache/ssl session was closed prematurely.

By using Google's DNS on a rooted device it worked.

The only thing left to do now is fix the our reverse DNS.

Here is a workaround : http://code.google.com/p/android/issues/detail?id=13117#c14

Call this method on your DefaultHttpClient or AndroidHttpClient instance. It will prevent the reverse DNS lookup from being made.

private void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) {
    // 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
    SocketFactory socketFactory = new LayeredSocketFactory() {
        SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
        @Override public Socket createSocket() throws IOException {
            return delegate.createSocket();
        }
        @Override public Socket connectSocket(Socket sock, String host, int port,
                InetAddress localAddress, int localPort, HttpParams params) throws IOException {
            return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
        }
        @Override public boolean isSecure(Socket sock) throws IllegalArgumentException {
            return delegate.isSecure(sock);
        }
        @Override public Socket createSocket(Socket socket, String host, int port,
                boolean autoClose) throws IOException {
            injectHostname(socket, host);
            return delegate.createSocket(socket, host, port, autoClose);
        }
        private void injectHostname(Socket socket, String host) {
            try {
                Field field = InetAddress.class.getDeclaredField("hostName");
                field.setAccessible(true);
                field.set(socket.getInetAddress(), host);
            } catch (Exception ignored) {
            }
        }
    };
    client.getConnectionManager().getSchemeRegistry()
            .register(new Scheme("https", socketFactory, 443));
}

Upvotes: 2

himanshu
himanshu

Reputation: 97

ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

nameValuePairs.add(new BasicNameValuePair("year","1980"));

//http post

try{

        HttpClient httpclient = new DefaultHttpClient();

        HttpPost httppost = new HttpPost("http://example.com/getAllPeopleBornAfter.php");

        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();

InputStream is = entity.getContent();

}catch(Exception e){

        Log.e("log_tag", "Error in http connection "+e.toString());

}

//convert response to string

try{

BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);

        StringBuilder sb = new StringBuilder();

String line = null;

while ((line = reader.readLine()) != null) {

                sb.append(line + "n");

}

        is.close();

       result=sb.toString();

}catch(Exception e){

        Log.e("log_tag", "Error converting result "+e.toString());

}

refer this code for http connection

Upvotes: -1

Nicklas A.
Nicklas A.

Reputation: 7061

Have you tried the solution mentioned in HttpClient on Android : NoHttpResponseException through UMTS/3G?

Copy below


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);

Upvotes: 1

Related Questions