Skip to content

Commit

Permalink
Merge pull request #25 from jgilfelt/gzip
Browse files Browse the repository at this point in the history
Decompress gzip encoded request/response bodies when used as a network interceptor
  • Loading branch information
jgilfelt authored Feb 22, 2017
2 parents 0c90a36 + 75da679 commit 5c795ce
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.util.Log;

import com.readystatesoftware.chuck.internal.data.ChuckContentProvider;
import com.readystatesoftware.chuck.internal.data.HttpTransaction;
Expand All @@ -42,6 +43,8 @@
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
import okio.BufferedSource;
import okio.GzipSource;
import okio.Okio;

/**
* An OkHttp Interceptor which persists and displays HTTP activity in your application for later inspection.
Expand All @@ -67,6 +70,7 @@ public enum Period {
FOREVER
}

private static final String LOG_TAG = "ChuckInterceptor";
private static final Period DEFAULT_RETENTION = Period.ONE_WEEK;
private static final Charset UTF8 = Charset.forName("UTF-8");

Expand Down Expand Up @@ -143,9 +147,10 @@ public ChuckInterceptor retainDataFor(Period period) {
}
}

transaction.setRequestBodyIsPlainText(!bodyEncoded(request.headers()));
transaction.setRequestBodyIsPlainText(!bodyHasUnsupportedEncoding(request.headers()));
if (hasRequestBody && transaction.requestBodyIsPlainText()) {
Buffer buffer = new Buffer();
BufferedSource source = getNativeSource(new Buffer(), bodyGzipped(request.headers()));
Buffer buffer = source.buffer();
requestBody.writeTo(buffer);
Charset charset = UTF8;
MediaType contentType = requestBody.contentType();
Expand Down Expand Up @@ -187,9 +192,9 @@ public ChuckInterceptor retainDataFor(Period period) {
}
transaction.setResponseHeaders(response.headers());

transaction.setResponseBodyIsPlainText(!bodyEncoded(response.headers()));
transaction.setResponseBodyIsPlainText(!bodyHasUnsupportedEncoding(response.headers()));
if (HttpHeaders.hasBody(response) && transaction.responseBodyIsPlainText()) {
BufferedSource source = responseBody.source();
BufferedSource source = getNativeSource(response);
source.request(Long.MAX_VALUE);
Buffer buffer = source.buffer();
Charset charset = UTF8;
Expand Down Expand Up @@ -259,9 +264,16 @@ private boolean isPlaintext(Buffer buffer) {
}
}

private boolean bodyEncoded(Headers headers) {
private boolean bodyHasUnsupportedEncoding(Headers headers) {
String contentEncoding = headers.get("Content-Encoding");
return contentEncoding != null &&
!contentEncoding.equalsIgnoreCase("identity") &&
!contentEncoding.equalsIgnoreCase("gzip");
}

private boolean bodyGzipped(Headers headers) {
String contentEncoding = headers.get("Content-Encoding");
return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
return "gzip".equalsIgnoreCase(contentEncoding);
}

private String readFromBuffer(Buffer buffer, Charset charset) {
Expand All @@ -278,4 +290,25 @@ private String readFromBuffer(Buffer buffer, Charset charset) {
}
return body;
}

private BufferedSource getNativeSource(BufferedSource input, boolean isGzipped) {
if (isGzipped) {
GzipSource source = new GzipSource(input);
return Okio.buffer(source);
} else {
return input;
}
}

private BufferedSource getNativeSource(Response response) throws IOException {
if (bodyGzipped(response.headers())) {
BufferedSource source = response.peekBody(maxContentLength).source();
if (source.buffer().size() < maxContentLength) {
return getNativeSource(source, true);
} else {
Log.w(LOG_TAG, "gzip encoded response was too long");
}
}
return response.body().source();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private void doHttpActivity() {
SampleApiService.HttpbinApi api = SampleApiService.getInstance(getClient(this));
Callback<Void> cb = new Callback<Void>() {
@Override public void onResponse(Call call, Response response) {}
@Override public void onFailure(Call call, Throwable t) {}
@Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); }
};
api.get().enqueue(cb);
api.post(new SampleApiService.Data("posted")).enqueue(cb);
Expand Down

0 comments on commit 5c795ce

Please sign in to comment.