Kiwi
Kiwi

Reputation: 2773

SSLHandshakeException: Connection closed by peer on android app

I'm developing an app for my company, that needs to post some data on an https url.

I'm using retro fit, but I'm getting the following error SSLHandshakeException: Connection closed by peer

this is the code I'm using

Service Generator

public class ServiceGenerator {

    public static final String API_BASE_URL = "https://website.com/api/";

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    public static <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient.build()).build();
        return retrofit.create(serviceClass);
    }
}

Service

public interface ITrackTraceService {

    @Headers("Content-Type: application/json")
    @POST("beepbeep/postdata")
    Call<String> PostLocation(@Body DataInput input);

}

Call itself

Location location = getLocation();

        TrackTraceService.ITrackTraceService srv = ServiceGenerator.createService(TrackTraceService.ITrackTraceService.class);

        DataInput i = new DataInput();
        i.Eta = new Date();
        i.Reference = "123456789";
        i.Status = "Tracking";
        i.Device = new Device();
        i.Reading = new Reading();
        i.Reading.Time = new Date();
        i.Reading.Location = new DeviceLocation();
        i.Reading.Location.Accuracy = location.getAccuracy();
        i.Reading.Location.Altitude = (float) location.getAltitude();
        i.Reading.Location.Latitude = (float) location.getLatitude();
        i.Reading.Location.Longitude = (float) location.getLongitude();
        i.Reading.Location.Speed = (float) location.getSpeed();
        i.Reading.Location.Time = new Date(location.getTime());
        Call<String> call = srv.PostLocation(i);

        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {

                if (response.isSuccessful()) {
                    Log.d("Service", "onResponse");
                } else {
                    // error response, no access to resource?
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable throwable) {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                throwable.printStackTrace(pw);
                Log.d("Service", call.request().toString());
                Log.e("Service", "onFailure", throwable);
                Log.d("Error", throwable.getMessage());
            }
        });
    }

versions

compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile files('libs/converter-gson-2.0.2.jar')
compile files('libs/okhttp-3.3.1.jar')
compile files('libs/gson-2.6.2.jar')
compile files('libs/okio-1.8.0.jar')
compile files('libs/retrofit-2.0.2.jar')
compile files('libs/logging-interceptor-3.3.1.jar')
building for android API version 23

stacktrace

javax.net.ssl.SSLHandshakeException: Connection closed by peer
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:318)
    at okhttp3.internal.io.RealConnection.connectTls(RealConnection.java:239)
    at okhttp3.internal.io.RealConnection.establishProtocol(RealConnection.java:196)
    at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:171)
    at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
    at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187)
    at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123)
    at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93)
    at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
    at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
    at okhttp3.RealCall.getResponse(RealCall.java:243)
    at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
    at okhttp3.RealCall.access$100(RealCall.java:30)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
    Suppressed: javax.net.ssl.SSLHandshakeException: Connection closed by peer

Upvotes: 3

Views: 6497

Answers (2)

Sumit Jain
Sumit Jain

Reputation: 1150

I have faced the same issue

but in my case, the issue was my device was connected to the wifi but wifi router was not having the internet connection and then the exception was thrown

Upvotes: 3

Akhil Soman
Akhil Soman

Reputation: 2217

This error might occur if you are testing your app on a server without a valid certificate.

The best way would be to have a authorized SSL Certificate.

If its a testing server then try adding this code in your project and invoke it before you call your webservice.
PS : This code should be removed before you upload your app to PlayStore. And you should use a server with authorized SSL certificate.

private static void disableSSLCertificateChecking() {

    System.out.println("INSIDE DISABLE SSLC");
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // Not implemented
        }
    } };

    try {
        SSLContext sc = SSLContext.getInstance("TLS");

        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

Basically this code is ignoring any certificate(valid/invalid) received from the server.

Alternatively check this answer

Another answer i have read(some time back) states that changing the version of okhttp(IDK if this is your case, but the guy used retrofit too) to an older one might prevent this error.

Upvotes: -2

Related Questions