I'm trying to write an interceptor that compresses a request body using Gzip.
My server does not support compressed requests, so I'll be using an application/octet-stream
instead of Content-Type: gzip
and compress the request body manually, it will be decompressed manually at backend.
public class GzipRequestInterceptor implements Interceptor {
final String CONTENT_TYPE = "application/octet-stream";
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || CONTENT_TYPE.equals(originalRequest.header("Content-Type"))) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Type", CONTENT_TYPE)
.method(originalRequest.method(), gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody gzip(final RequestBody body) throws IOException {
final Buffer inputBuffer = new Buffer();
body.writeTo(inputBuffer);
final Buffer outputBuffer = new Buffer();
GZIPOutputStream gos = new GZIPOutputStream(outputBuffer.outputStream());
gos.write(inputBuffer.readByteArray());
inputBuffer.close();
gos.close();
return new RequestBody() {
@Override
public MediaType contentType() {
return body.contentType();
}
@Override
public long contentLength() {
return outputBuffer.size();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
ByteString snapshot = outputBuffer.snapshot();
sink.write(snapshot);
}
};
}
}
It doesn't work - 30 seconds after request is fired, a 500 Server Error
is received. On the server there's a timeout exception.
My guess is that I've done wrong with input/output on the gzip method... any ideas?
Update if I stop the app, the request goes through successfully, does this indicate that the app is still waiting for data from outputBuffer?