Reputation: 3430
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.
I'm starting to think that this could be better suited for serverfault.com
This is the dump file and the screenshot
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
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
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
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