4

I created a class to get refresh token if the token get expired at any time. Always call to this class before do a rest API call.

Here is my class,

import android.content.Context;

import com.epic.ssb.data.TokenModel;
import com.epic.ssb.security.LogoutProcess;
import com.epic.ssb.security.TokenIdentifier;
import com.epic.ssb.util.Constant;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RefreshTokenInterceptor implements Interceptor {

    private Lock lock = new ReentrantLock();
    Context ctx;

    public RefreshTokenInterceptor(Context context){
        this.ctx = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        chain.withConnectTimeout( 45, TimeUnit.SECONDS);
        chain.withReadTimeout(45,TimeUnit.SECONDS);
        chain.withWriteTimeout(45,TimeUnit.SECONDS);
        Request request = chain.request();
        Response response = chain.proceed(request);

        if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
            if (lock.tryLock()) {
                try {
                    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
                    httpClient.addInterceptor(new Interceptor() {
                        @Override
                        public Response intercept(Interceptor.Chain chain) throws IOException {
                            Request original = chain.request();

                            Request request = original.newBuilder()
                                    .header("Content-Type", "application/json")
                                    .header("X-Requested-With", "XMLHttpRequest")
                                    .header("X-Authorization", "Bearer " + TokenIdentifier.getREFRESHTOKEN())
                                    .method(original.method(), original.body())
                                    .build();

                            return chain.proceed(request);
                        }
                    });

                    OkHttpClient client = httpClient.build();
                    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(Constant.BASE_URL)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(client)
                            .build();

                    ApiService apiService = retrofit.create(ApiService.class);
                    Call<TokenModel> call = apiService.getTokenFromRefreshToken();

                    retrofit2.Response<TokenModel> response1 = call.execute();
                    if(response.body()!=null){
                        TokenModel tokenModel = response1.body();
                        TokenIdentifier.setTOKEN(tokenModel.getToken());
                    }

                    Request newRequest = recreateRequestWithNewAccessToken(chain);
                    return chain.proceed(newRequest);

                } catch (Exception ex) {
                    LogoutProcess.logout(ctx);
                    return response;
                } finally {
                    lock.unlock();
                }
            } else {
                lock.lock();
                lock.unlock();
                Request newRequest = recreateRequestWithNewAccessToken(chain);
                return chain.proceed(newRequest);
            }
        } else {
            return response;
        }
    }

    private Request recreateRequestWithNewAccessToken(Chain chain) {
        String freshAccessToken = TokenIdentifier.getTOKEN();
        return chain.request().newBuilder()
                .header("Content-Type", "application/json")
                .header("X-Requested-With", "XMLHttpRequest")
                .header("X-Authorization", "Bearer " + freshAccessToken)
                .method(chain.request().method(), chain.request().body())
                .build();
    }
}

Note : This class is using to get a new token if the current token is expired.

Then I got below exception randomly for above class is accessed,

W/System.err: java.net.SocketTimeoutException: timeout
W/System.err:     at okio.Okio$4.newTimeoutException(Okio.java:232)
        at okio.AsyncTimeout.exit(AsyncTimeout.java:285)
W/System.err:     at okio.AsyncTimeout$1.write(AsyncTimeout.java:184)
        at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:179)
        at okio.RealBufferedSink.write(RealBufferedSink.java:42)
        at okhttp3.internal.http1.Http1Codec$FixedLengthSink.write(Http1Codec.java:295)
        at okio.ForwardingSink.write(ForwardingSink.java:35)
        at okhttp3.internal.http.CallServerInterceptor$CountingSink.write(CallServerInterceptor.java:149)
W/System.err:     at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:179)
        at okio.RealBufferedSink.write(RealBufferedSink.java:48)
        at okhttp3.RequestBody$1.writeTo(RequestBody.java:73)
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:72)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err:     at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err:     at com.epic.ssb.network.RefreshTokenInterceptor.intercept(RefreshTokenInterceptor.java:39)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
W/System.err: Caused by: java.net.SocketException: Socket closed
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:124)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:161)
        at okio.Okio$1.write(Okio.java:79)
        at okio.AsyncTimeout$1.write(AsyncTimeout.java:180)
W/System.err:   ... 30 more

As I mentioned on the top of the post, this is using for secured Rest API calls. Not for unauthorized Rest API calls.

why is this happening randomly ? Should I add more steps ?

Terance Wijesuriya
  • 1,928
  • 9
  • 31
  • 61
  • 2
    Possible duplicate of [Retrofit2 SocketTimeOutException](https://stackoverflow.com/questions/47785086/retrofit2-sockettimeoutexception) – Hemant Parmar Jul 18 '19 at 06:58
  • @HemantParmar : Totally different. I used for get access token and refresh token. Though I followed https://stackoverflow.com/questions/47785086/retrofit2-sockettimeoutexception I couldn't get any result – Terance Wijesuriya Jul 18 '19 at 07:00

0 Answers0