I'm using Volley library in Android in my application and when trying to make POST requests to our server I get the following error:
com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6821edb0: Failure in SSL library, usually a protocol error
error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:744 0x5f4c0c46:0x00000000)
Our server is signed with the following SSL certificate:
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
The certificate is described by openssl as follows:
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
I checked the Cipher over Android enabled ciphers and they say it is enabled by default.
I have tried the following solution for this problem, but none of them solved it:
HTTPS support for Volley Android networking library - not working (also not suitable for me since it's not secure)
How to disable SSLv3 in android for HttpsUrlConnection? - I've tried this, the error still occurs
The Android Api used in out project is Android 5.1 (API 22). The Volley library version is 1.0.15 (Also tried with the latest one, 1.0.18 but the issue still occurs).
One other solution I've tried was using okhttp library, integrated with Volley, but the issue still occurs.
Any working solution would be much appreciated.
Thank you in advance!
UPDATE
By the way, I managed to get supported ciphers from the server:
Supported cipher suites (ORDER IS NOT SIGNIFICANT):
SSLv3
RSA_WITH_RC4_128_MD5
RSA_WITH_RC4_128_SHA
RSA_WITH_IDEA_CBC_SHA
RSA_WITH_3DES_EDE_CBC_SHA
DHE_RSA_WITH_3DES_EDE_CBC_SHA
RSA_WITH_AES_128_CBC_SHA
DHE_RSA_WITH_AES_128_CBC_SHA
RSA_WITH_AES_256_CBC_SHA
DHE_RSA_WITH_AES_256_CBC_SHA
RSA_WITH_CAMELLIA_128_CBC_SHA
DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
RSA_WITH_CAMELLIA_256_CBC_SHA
DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_RSA_WITH_SEED_CBC_SHA
TLS_DHE_RSA_WITH_SEED_CBC_SHA
(TLSv1.0: idem)
(TLSv1.1: idem)
TLSv1.2
RSA_WITH_RC4_128_MD5
RSA_WITH_RC4_128_SHA
RSA_WITH_IDEA_CBC_SHA
RSA_WITH_3DES_EDE_CBC_SHA
DHE_RSA_WITH_3DES_EDE_CBC_SHA
RSA_WITH_AES_128_CBC_SHA
DHE_RSA_WITH_AES_128_CBC_SHA
RSA_WITH_AES_256_CBC_SHA
DHE_RSA_WITH_AES_256_CBC_SHA
RSA_WITH_AES_128_CBC_SHA256
RSA_WITH_AES_256_CBC_SHA256
RSA_WITH_CAMELLIA_128_CBC_SHA
DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
DHE_RSA_WITH_AES_128_CBC_SHA256
DHE_RSA_WITH_AES_256_CBC_SHA256
RSA_WITH_CAMELLIA_256_CBC_SHA
DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_RSA_WITH_SEED_CBC_SHA
TLS_DHE_RSA_WITH_SEED_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
From what I read , there should be no problem with these ciphers on API LVL 22.
I found the problem after hours of searching through the Internet and project code:
Inside the project I have a class named JsonToPOJORequest<T>
, that extends the Volley class JsonRequest<T>
.
This is the class that actually makes the request for every method on the server.
After analysing the code a little bit, I found a method call inside the constructor, as follows:
setRetryPolicy(new DefaultRetryPolicy(3*DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0));
where DefaultRetryPolicy.DEFAULT_TIMEOUT_MS
is set as 2500 ms.
Because the POST request had a lot of data, it takes more time to send the request and receive the response back from server.
It seems that Volley didn't wait enough for the response to come and throws a TimeoutError. So, the request was made, everything goes well on the server, but the client(Android) does not wait for the server and gets an error.
The solution was to set the Timeout parameter to be higher or 0, like this:
setRetryPolicy(new DefaultRetryPolicy(5*DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0));
setRetryPolicy(new DefaultRetryPolicy(0, 0, 0));
The two questions that remain are:
1) Why does it take so long to make the request? -> 3*2500 = 7500ms is quite a lot of time(over 7 seconds) to make a request. And this is not a server problem, since on iOS it works just fine.
2) Why does the VolleyError look like this?
com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted:
Should be TimeoutError and not NoConnectionError.
You can find more information about this bug here, were I also deduced the solution: Android Volley double post when have slow request
https://groups.google.com/forum/#!topic/volley-users/8PE9dBbD6iA
The solution is to increase the request timeout of volley by this this line of code.
request.setRetryPolicy(new DefaultRetryPolicy(10 * 1000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
above code is settings request timeout to 10 seconds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With