python 请求库在POST请求中未正确发送gzip有效负载

7vux5j2d  于 2023-05-16  发布在  Python
关注(0)|答案(1)|浏览(134)

我有一个服务器,它接受POST请求体中的gzip有效载荷。因此,我使用Python gzip库压缩数据,并使用requests库发送压缩的有效负载。服务器返回201响应,但在稍后的处理过程中,它抱怨消息不是以GZip幻数开头的。服务器是间歇性地这样做的,所以我假设这与客户端如何以块的形式发送数据有关。
为了验证服务器是否确实接受gzip压缩的数据,我创建了相同代码的Java版本并发送了请求。在这种情况下,服务器能够正确地处理数据。
我创建了一个简单的echo服务器,并发送了相同的请求,一次来自Java,一次来自Python。Java客户端设置Transfer-Encoding: chunked头并发送有效负载,而Python客户端设置Content-Length: ...头并发送有效负载。据我所知,这两种方法应该是一样的。我不知道我做错了什么,我不知道我还能做些什么来调试,因为我没有访问服务器配置或日志。
这是Python客户端代码:

headers = {
    'Content-Type': 'application/gzip',
    'Content-Encoding': 'gzip'
}

httpSession = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=3, pool_connections=5)
httpSession.mount('https://', adapter=adapter)

compressedData = gzip.compress(data=data.encode('utf-8'), compresslevel=1)
response = httpSession.post(url=..., data=compressedData, headers=headers)

下面是用于比较的Java客户端代码:

HttpPost httpPost = new HttpPost();
httpPost.setURI(new URI("..."));
CustomCompressionEntity compressionEntity = new CustomCompressionEntity (new StringEntity("something"));
httpPost.setEntity(compressionEntity);
httpPost.setHeader(new BasicHeader("Content-Type","application/gzip"));

CloseableHttpClient httpclient = HttpClients.createDefault();
org.apache.http.HttpResponse response = httpclient.execute(httpPost);
EntityUtils.consumeQuietly(response.getEntity());

CustomCompressionEntity是一个创建gzip流的基本 Package 器:

public class CustomCompressionEntity extends HttpEntityWrapper {
    private static final String GZIP_CODEC = "gzip";
    public CustomCompressionEntity(HttpEntity entity) {
        super(entity);
    }
    public Header getContentEncoding() {
        return new BasicHeader("Content-Encoding", "gzip");
    }
    public long getContentLength() {
        return -1L;
    }
    public boolean isChunked() {
        return true;
    }
    public InputStream getContent() throws IOException {
        throw new UnsupportedOperationException();
    }
    public void writeTo(OutputStream outStream) throws IOException {
        Args.notNull(outStream, "Output stream");
        GZIPOutputStream gzip = new GZIPOutputStream(outStream){{def.setLevel(1);}};
        this.wrappedEntity.writeTo(gzip);
        gzip.close();
    }
}

请帮助我找出我做错了什么,或者至少我可以看看下一步。

bvjxkvbb

bvjxkvbb1#

结果是我这边出了错。我没有停止发送未压缩数据的线程,服务器无法处理来自同一客户端的压缩和未压缩数据。

相关问题