SSL exception when using Volley

I use Volley on Android to fulfill my application requests. Unfortunately, I get the following error:

com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x61e15f78: 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 0x5b647c58:0x00000000) 

I use two Fragments , inside the ViewPager , which request their contents during onResume. The request URL is basically the same as the request parameter (which sets the type of content, for example, trend versus hot).

The URL is https://host/api/content?type={hot/trending} . Authorization is performed through the request header.

The strange part about this exception is that only one of the two queries fails and changes from time to time. After I added a delay between them, the exception stopped (strangely indicating some kind of race condition?). But this seems like a bad workaround, and I would like to solve it correctly.

Any thoughts on what might be causing this?

EDIT:

A request is created in a standard way using a singleton that provides a queue as follows:

 final RequestQueue requestQueue = RequestQueueSingleton.getInstance(getActivity()).getRequestQueue(); final GsonRequestGet<SearchApiWrapper> gsonRequest = new GsonRequestGet<>(clazz, url,successListener, errorListener); gsonRequest.setRetryPolicy(new DefaultRetryPolicy(3000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); gsonRequest.setTag(mTag); requestQueue.add(gsonRequest); 

And here is the singleton class:

 public class RequestQueueSingleton { private static RequestQueueSingleton mInstance; private RequestQueue mRequestQueue; private Context mContext; public RequestQueueSingleton(Context context) { mContext = context; mRequestQueue = getRequestQueue(); } /** * Returns a instance of this singleton */ public static synchronized RequestQueueSingleton getInstance(Context context) { if (mInstance == null) { mInstance = new RequestQueueSingleton(context); } return mInstance; } /** * Returns instance of the request queue */ public RequestQueue getRequestQueue() { if (mRequestQueue == null) { mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext()); } return mRequestQueue; } } 
+7
android android-volley
source share
2 answers

After our comments, maybe this can help you:

Your requestQueue :

 static { requestQueue = Volley.newRequestQueue(Application.getContext(), new HurlStack(null, ClientSSLSocketFactory.getSocketFactory())); } 

ClientSSLSocketFactory :

 public class ClientSSLSocketFactory extends SSLCertificateSocketFactory { private SSLContext sslContext; public static SSLSocketFactory getSocketFactory(){ try { X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {} public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {} public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = ClientSSLSocketFactory.getDefault(10000, new SSLSessionCache(Application.getInstance())); return ssf; } catch (Exception ex) { return null; } } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } @Override public Socket createSocket() throws IOException { return sslContext.getSocketFactory().createSocket(); } } 
+3
source share

Add the following import statuses.

 import javax.net.ssl.TrustManager; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; import java.util.ResourceBundle; 

and add the following code before making a network call.

  TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; SSLContext sc = null; try { sc = SSLContext.getInstance("SSL"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } try { sc.init(null, trustAllCerts, new java.security.SecureRandom()); } catch (KeyManagementException e) { e.printStackTrace(); } HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // Create all-trusting host name verifier HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; // Install the all-trusting host verifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); 
+1
source share

All Articles