Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL Exception when using Volley

I'm using Volley in Android to perform my app requests. Unfortunately, I'm getting 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'm using two Fragments, inside a ViewPager, which request their content during onResume. The requests url is basically the same but for a query parameter (which set the type of content, e.g. trending vs hot).

The url is in the form https://host/api/content?type={hot/trending}. Authorization is done through the request header.

The weird part about this exception is that only one of the two requests fail and it varies which one from time to time. After I added a delay between them, the exception stopped occurring (oddly pointing to some race condition?). But this seems a bad workaround and I'd like to solve this the right way.

Any thoughts on what could be the cause of it?

EDIT:

The request is created the standard way, using a singleton providing the 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;
    }
}
like image 436
Edson Menegatti Avatar asked Jun 18 '15 20:06

Edson Menegatti


People also ask

Is volley deprecated?

GitHub - mcxiaoke/android-volley: DEPRECATED.

What is volley dependency?

Volley is an HTTP library that makes networking for Android apps easier and most importantly, faster. Volley is available on GitHub. Volley offers the following benefits: Automatic scheduling of network requests. Multiple concurrent network connections.

Is volley a REST API?

Android Volley and Retrofit are the most used libraries for accessing the REST Web APIs today.


1 Answers

Add following import statments.

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 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);
like image 120
Developine Avatar answered Sep 21 '22 02:09

Developine