diff --git a/pom.xml b/pom.xml
index 3ab675c..179e3f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
4.0.0
rest-client
- 0.0.9
+ 0.0.10
RestClient
jar
@@ -33,5 +33,10 @@
okhttp
3.14.9
+
+ com.squareup.okio
+ okio
+ 1.17.2
+
\ No newline at end of file
diff --git a/src/main/java/info/unterrainer/commons/restclient/BaseBuilder.java b/src/main/java/info/unterrainer/commons/restclient/BaseBuilder.java
index f21713e..2b0d6fe 100644
--- a/src/main/java/info/unterrainer/commons/restclient/BaseBuilder.java
+++ b/src/main/java/info/unterrainer/commons/restclient/BaseBuilder.java
@@ -41,6 +41,19 @@ protected enum Retry {
protected Map headers = new HashMap<>();
protected Map parameters = new HashMap<>();
protected Retry retry = Retry.ONCE;
+ protected boolean isGZipped;
+
+ /**
+ * Adds the header {@code "Content-Encoding": "gzip"} which triggers
+ * GZIP-compression within our RestClient.
+ *
+ * @return a {@link BaseBuilder} to provide a fluent interface.
+ */
+ @SuppressWarnings("unchecked")
+ public R gzip() {
+ addHeader("Content-Encoding", "gzip");
+ return (R) this;
+ }
/**
* Add a string to an URL.
diff --git a/src/main/java/info/unterrainer/commons/restclient/GzipInterceptor.java b/src/main/java/info/unterrainer/commons/restclient/GzipInterceptor.java
new file mode 100644
index 0000000..ed53626
--- /dev/null
+++ b/src/main/java/info/unterrainer/commons/restclient/GzipInterceptor.java
@@ -0,0 +1,92 @@
+package info.unterrainer.commons.restclient;
+
+import java.io.IOException;
+
+import okhttp3.Headers;
+import okhttp3.Interceptor;
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.Request.Builder;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.ResponseBody;
+import okio.BufferedSink;
+import okio.GzipSink;
+import okio.GzipSource;
+import okio.Okio;
+
+public class GzipInterceptor implements Interceptor {
+ @Override
+ public Response intercept(final Interceptor.Chain chain) throws IOException {
+
+ Request originalRequest = chain.request();
+
+ if (acceptGzipAlreadySetAndNoContentToZip(originalRequest))
+ return chain.proceed(originalRequest);
+
+ Builder newRequestBuilder = originalRequest.newBuilder().addHeader("Accept-Encoding", "gzip");
+ if (contentToZip(originalRequest))
+ newRequestBuilder.method(originalRequest.method(), gzip(originalRequest.body()));
+
+ // Make the call.
+ Response response = chain.proceed(newRequestBuilder.build());
+
+ if (isGzipped(response))
+ return unzip(response);
+ else
+ return response;
+ }
+
+ private boolean acceptGzipAlreadySetAndNoContentToZip(final Request originalRequest) {
+ return originalRequest.header("Accept-Encoding") == "gzip"
+ && (originalRequest.body() == null || originalRequest.header("Content-Encoding") != "gzip");
+ }
+
+ private RequestBody gzip(final RequestBody body) {
+ return new RequestBody() {
+ @Override
+ public MediaType contentType() {
+ return body.contentType();
+ }
+
+ @Override
+ public long contentLength() {
+ return -1; // We don't know the compressed length in advance!
+ }
+
+ @Override
+ public void writeTo(final BufferedSink sink) throws IOException {
+ BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
+ body.writeTo(gzipSink);
+ gzipSink.close();
+ }
+ };
+ }
+
+ private Response unzip(final Response response) throws IOException {
+
+ if (response.body() == null)
+ return response;
+
+ GzipSource gzipSource = new GzipSource(response.body().source());
+ String bodyString = Okio.buffer(gzipSource).readUtf8();
+
+ ResponseBody responseBody = ResponseBody.create(response.body().contentType(), bodyString);
+
+ Headers strippedHeaders = response.headers()
+ .newBuilder()
+ .removeAll("Content-Encoding")
+ .removeAll("Content-Length")
+ .build();
+ return response.newBuilder().headers(strippedHeaders).body(responseBody).message(response.message()).build();
+
+ }
+
+ private Boolean isGzipped(final Response response) {
+ return response.header("Content-Encoding") != null && response.header("Content-Encoding").equals("gzip");
+ }
+
+ private boolean contentToZip(final Request originalRequest) {
+ return originalRequest.body() != null && originalRequest.header("Content-Encoding") == "gzip";
+ }
+}
diff --git a/src/main/java/info/unterrainer/commons/restclient/Information.java b/src/main/java/info/unterrainer/commons/restclient/Information.java
new file mode 100644
index 0000000..bf6bc15
--- /dev/null
+++ b/src/main/java/info/unterrainer/commons/restclient/Information.java
@@ -0,0 +1,7 @@
+package info.unterrainer.commons.restclient;
+
+public class Information {
+ public static final String name = "REST-Client";
+ public static final String buildTime = "2021-06-28T07:57:53Z";
+ public static final String pomVersion = "0.0.10";
+}
diff --git a/src/main/java/info/unterrainer/commons/restclient/RestClient.java b/src/main/java/info/unterrainer/commons/restclient/RestClient.java
index bad13e8..7e1bbcc 100644
--- a/src/main/java/info/unterrainer/commons/restclient/RestClient.java
+++ b/src/main/java/info/unterrainer/commons/restclient/RestClient.java
@@ -48,6 +48,7 @@ public RestClient(final JsonMapper jsonMapper, final String userName, final Stri
.connectTimeout(connectTimeoutInMillis, TimeUnit.MILLISECONDS)
.readTimeout(readTimeoutInMillis, TimeUnit.MILLISECONDS)
.writeTimeout(writeTimeoutInMillis, TimeUnit.MILLISECONDS)
+ .addInterceptor(new GzipInterceptor())
.followRedirects(true);
if (userName != null || password != null)
c.authenticator((route, response) -> {