HttpClient on Android : NoHttpResponseException through UMTS/3G
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);
HttpClient on Android : NoHttpResponseException through UMTS/3G
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);
Android HttpGet throws NoHttpResponseException half the time?
turns out it was the server that was the problem. The way the server was setup it was not getting enough time to process the incoming request. The solution to the problem can be found in this link.
Spinneret web server fix
Android: org.apache.http.NoHttpResponseException: The target server failed to respond
I finally figured out what the problems is. When I do the Base64 encoding of the username and password, I use the wrong flag for Base64.encodeToString(...). So I change the falg:
FROM:
basicAuth = Base64.encodeToString(basicAuth.getBytes(), Base64.DEFAULT);
TO:
basicAuth = Base64.encodeToString(basicAuth.getBytes(), Base64.NO_WRAP);
... and everything is working just fine.
Https connection Android
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));
}
Android Froyo: Connection to https using trusting all socket factory results in target server failed to respond
And now the issue was resolved.
The problem was not with the java / Android code but with the server configuration. The case was the following: I was trying to access the development environment server. However, it turned out our infrastructure engineer configured it with exactly the same certificate as the production server. This meant that the hostname in the certificate was erronous (matching the production environment).
Weird enough these web services were accessible through Firefox and Chrome, even with the wrong certificate, which caused all the confusion.
Hopefully describing my case here will help others in the future sort out the same problem.
duplicate requests from HttpClient
So what appears to be happening here is that your client sends a request, does not get a response in a timely manner, and as a result retries the same request again (as it should). This, in turn, results in multiple POST
requests being sent to your server (almost in succession), which your server cannot currently deal with appropriately.
To verify/debug this, try disabling HTTP retries as follows:
defaultHttpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler
(0, false));
This of course will deal with your duplicate requests issue, but then introduces another more serious issue; namely, it will try once (and only once) and fail. From the information I got from your comments, here are a few ideas you can try:
Please bare with the pseudocode as I don't have all the details of how your client is architected
Handle Multiple POSTS in Succession
- Disable automatic retries (as above)
- Wrap your
POST
requests in a loop similar to how this is implemented - Then either
sleep
between your manual retries or implement your version of exponential backoff
No matter what, your server will need the capability to handle duplicate requests in a reasonable way, this is HTTP afterall. However, you're at least giving it a chance to process the first one before it's bombarded with duplicates.
I recommend that the first step it takes when processing a request is to set some form of a (duplicate) flag. Then if/when it receives a dupe, it continues processing the first request (as usual) and silently ignores the dupes.
So just to summarize, the point of this whole scheme was to give your server a chance to set the dupe flag. After that, it's your server's job to discard (or handle) duplicate requests as needed. Does this all make sense?
Related Topics
Android:Dither="True" Does Not Dither, What's Wrong
How to Close the Status Bar/Notification Panel After Notification Button Click
Why Is Calling Process.Killprocess(Process.Mypid()) a Bad Idea
Camera in Android, How to Get Best Size, Preview Size, Picture Size, View Size, Image Distorted
Android: How to Create Fade-In/Fade-Out Sound Effects for Any Music File That My App Plays
Retrofit2: Modifying Request Body in Okhttp Interceptor
Saving Arraylists in SQLite Databases
Rotate Zoom Drag Image in Android Imageview
Practical Way to Find Out If Sms Has Been Sent
Dagger 2 Injecting Android Application Context
Android - Getting from a Uri to an Inputstream to a Byte Array
Android Maps API V2 Draw Circle
How to Detect Bottom Soft Navigation Bar Available in Android Programmatically
Creating a Product Sdk: How to Add a Native Lib (.So) and a Jar with the Sdk I am Creating
Android Emulator Screen Fills Up Only Some Fraction Part of Actual Android Emulator Screen
How to Change the Proguard Mapping File Name in Gradle for Android Project
Could Not Resolve Com.Android.Support:Appcompat-V7:26.1.0 in Android Studio New Project