我正在尝试编写一个使用 Gzip 压缩请求正文的拦截器。
我的服务器不支持压缩请求,所以我将使用 anapplication/octet-stream
而不是 Content-Type: gzip
手动压缩请求正文,它将在后端手动解压缩。
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);
}
};
}
}
它不起作用 - 触发请求 30 秒后,500 Server Error
收到 a 。在服务器上有一个超时异常。
我的猜测是我在 gzip 方法的输入/输出上做错了……有什么想法吗?
更新如果我停止应用程序,请求成功通过,这是否表明应用程序仍在等待来自 outputBuffer 的数据?