2

Overview

I am using the below version of Okhttp com.squareup.okhttp3:okhttp:4.9.3

I need to execute multiple HttpRequests at one go when a transaction happens.

I have taken Singleton OkHttpClient to avoid creation of new client every time so I am reusing the same http client for all my http requests

Scenario

When I execute multiple http requests pararell using the same Singleton OkHttpClient, the SSL Handshake is happening for the 1st http request and it is not happening for the other http requests.

Problem Statement

If there is a delay of more than 30 seconds between 2 http requests then the SSL Handshake is happening every time .. I want to address this issue. SSL Handshake should happen only for the 1st http request. I may send a http request now and take some time and then send another http request. I dont want SSL handshake to happen for the 2nd httprequest. Right now it is happening if there is a delay of 30 seconds. If I execute multiple http requests without any time delay then it is working fine.

Is there any setting in OkttpClient where I can increase the idle time out between 2 http requests so that SSL Handshake wont happen every time.

public class OkHttpSingleton {

private static OkHttpSingleton singletonInstance;

// No need to be static; OkHttpSingleton is unique so is this.
private OkHttpClient httpClient;
int timeoutConnect = 45000;
int timeoutSocket = 45000;


// Private so that this cannot be instantiated.
private OkHttpSingleton() {
    try {
        String tlsVersion = "TLSv1.2";
        if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            tlsVersion = "TLSv1";
        }
        SSLContext sslContext = SSLContext.getInstance(tlsVersion);
        sslContext.init(null, null, null);
        SSLSocketFactory socketFactory = sslContext.getSocketFactory();

        httpClient = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(timeoutConnect, TimeUnit.SECONDS)
                .writeTimeout(timeoutSocket, TimeUnit.SECONDS)
                .readTimeout(timeoutSocket, TimeUnit.SECONDS)
                .sslSocketFactory(socketFactory, new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                })
                .build();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static OkHttpSingleton getInstance() {
    if (singletonInstance == null) {
        singletonInstance = new OkHttpSingleton();
    }
    return singletonInstance;
}

// In case you just need the unique OkHttpClient instance.
public OkHttpClient getClient() {
    return httpClient;
}

public void closeConnections() {
    httpClient.dispatcher().cancelAll();
}

}

Pls find the screenshot of WIRESHARK below . I want to avoid that Client Hello and HandShake

enter image description here

Pls find the RST ACK sent by server after 30 seconds of inactivity

enter image description here

11
  • You define a read and write time-out of 45 seconds, so if a HTTP connection is not used for 45 seconds in outgoing or incoming direction it will be closed and next time a request is executed you will see a TLS handshake. If you want avoid TLS handshake increase or kick both values. Commented Aug 28, 2023 at 8:26
  • 1
    Are you sure that what you want is supported by the server? There may need to be some server-side configuration needed to support multiple HTTP requests over a single TLS session. Commented Aug 28, 2023 at 10:51
  • Dear @CommonsWare I am not aware the server side configuration, but will verify it once. Thank you so much for the input :) Commented Aug 28, 2023 at 12:22
  • @Robert I tried by changing the value from 45 seconds to 10 seconds .. When I try to execute the request after 30 seconds delay it is again making SSL Handshake. ... Commented Aug 28, 2023 at 12:25
  • 1
    Carefully check the Wireshark log who closes the connection. If it is the server you can only test if keep-alive changes something. If not then this is the way the server wants to handle connections. Commented Aug 28, 2023 at 15:18

1 Answer 1

1

You can influence the idle time for connections, which indirectly affects the TLS handshake timeout. You do this by configuring the connection pool's eviction policy and the keep-alive duration.

// Increase the idle connection timeout to 10 minutes
ConnectionPool connectionPool = new ConnectionPool(
    /* maxIdleConnections */ 5,
    /* keepAliveDuration */ 10, TimeUnit.MINUTES
);

OkHttpClient client = new OkHttpClient.Builder()
    .connectionPool(connectionPool)
    .build();

In the code above, the keepAliveDuration parameter in the ConnectionPool constructor specifies how long connections can remain idle before they are considered for eviction and cleanup. By increasing this value, you can indirectly influence the timeout for the TLS handshake.

Hope it helps!

Sign up to request clarification or add additional context in comments.

1 Comment

I tried this but no luck the client hello is calling when I execute http request after 40 seconds. ... :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.