0

我正在尝试编写一个使用 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 的数据?

4

1 回答 1

0

这是您正在寻找的拦截器,请查看重写请求章节。

于 2015-10-07T08:50:13.283 回答