Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android - OkHttp interceptor - response already "consumed"

I'm trying to use this interceptor for authentication:

public class CustomInterceptor implements Interceptor {

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();

    // try the request
    Response response = chain.proceed(request);

    if (response shows expired token) {

        // get a new token (I use a synchronous Retrofit call)

        // create a new request and modify it accordingly using the new token
        Request newRequest = request.newBuilder()...build();

        // retry the request
        return chain.proceed(newRequest);
    }

    // otherwise just pass the original response on
    return response;
}

The problem is that my check (response shows expired token) is not status-related, I need to check the actual response (body content). So after the check, the response is "consumed" and any attempt to ready the body will fail.

I've tried to "clone" the response buffer before read, like:

public static String responseAsString(Response response ){
    Buffer clonedBuffer = response.body().source().buffer().clone();
    return ByteString.of(clonedBuffer.readByteArray()).toString();
}

but it doesn't work, the clonedBuffer is empty. Any help will be appreciated.

like image 496
aw4y Avatar asked Apr 21 '15 18:04

aw4y


1 Answers

I just had the same problem myself, and the solution I found was to consume the response's body and build a new response with a new body. I did it like so:

...

Response response = chain.proceed(request);
MediaType contentType = response.body().contentType();

String bodyString = response.body().string();
if (tokenExpired(bodyString)) {
    // your logic here...
}

ResponseBody body = ResponseBody.create(contentType, bodyString);
return response.newBuilder().body(body).build();
like image 179
Arthur Avatar answered Nov 13 '22 20:11

Arthur