简体   繁体   English

编写可压缩请求正文的OkHttp拦截器

[英]Writing an OkHttp Interceptor that compresses request body

I'm trying to write an interceptor that compresses a request body using Gzip. 我正在尝试编写一个拦截器,该拦截器使用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. 我的服务器不支持压缩的请求,因此我将使用application/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);
            }
        };
    }
}

It doesn't work - 30 seconds after request is fired, a 500 Server Error is received. 它不起作用-触发请求后30秒钟,收到500 Server Error 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? 我的猜测是我对gzip方法的输入/输出做错了...有什么想法吗?

Update if I stop the app, the request goes through successfully, does this indicate that the app is still waiting for data from outputBuffer? 如果我停止了该应用程序,则更新成功,请求成功通过,这是否表明该应用程序仍在等待outputBuffer的数据?

这是您在寻找拦截器的内容 ,请检查“重写请求”一章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM