Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - OKHttp: how to enable gzip for POST

In our Android App, I'm sending pretty large files to our (NGINX) server so I was hoping to use gzip for my Retrofit POST message.

There are many documentations about OkHttp using gzip transparently or changing the headers in order to accept gzip (i.e. in a GET message).

But how can I enable this feature for sending gzip http POST messages from my device? Do I have to write a custom Intercepter or something? Or simply add something to the headers?

like image 474
Tobias Reich Avatar asked Dec 04 '17 16:12

Tobias Reich


1 Answers

According to the following recipe: The correct flow for gzip would be something like this:

OkHttpClient client = new OkHttpClient.Builder()
      .addInterceptor(new GzipRequestInterceptor())
      .build();

/** This interceptor compresses the HTTP request body. Many webservers can't handle this! */
  static class GzipRequestInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
      Request originalRequest = chain.request();
      if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
        return chain.proceed(originalRequest);
      }

      Request compressedRequest = originalRequest.newBuilder()
          .header("Content-Encoding", "gzip")
          .method(originalRequest.method(), gzip(originalRequest.body()))
          .build();
      return chain.proceed(compressedRequest);
    }

    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(BufferedSink sink) throws IOException {
          BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
          body.writeTo(gzipSink);
          gzipSink.close();
        }
      };
    }
  }
like image 132
Leanid Vouk Avatar answered Oct 16 '22 06:10

Leanid Vouk