(这个问题不是关于 gzip
编码的 responses 来自网络服务器的透明解压;我知道 requests
handles that automatically。)
问题
我正在尝试将文件发布到 RESTful 网络服务。显然,requests
使这很容易做到:
files = dict(data=(fn, file))
response = session.post(endpoint_url, files=files)
在这种情况下,我的文件采用高度可压缩的格式(是的,XML),因此我想确保压缩请求正文。
服务器声称接受 gzip 编码(Accept-Encoding: gzip
在响应 header 中),所以我应该能够 gzip 整个请求体,对吧?
尝试的解决方案
这是我尝试完成这项工作的尝试:我首先构造请求并准备它,然后我进入 PreparedRequest
对象,抽出 body
,运行它gzip
,然后放回去。 (哦,不要忘记更新 Content-Length
和 Content-Encoding
header 。)
files = dict(data=(fn, file))
request = request.Request('POST',endpoint_url, files=files)
prepped = session.prepare_request(request)
with NamedTemporaryFile(delete=True) as gzfile:
gzip.GzipFile(fileobj=gzfile, mode="wb").write(prepped.body)
prepped.headers['Content-Length'] = gzfile.tell()
prepped.headers['Content-Encoding'] = 'gzip'
gzfile.seek(0,0)
prepped.body = gzfile.read()
response = session.send(prepped)
不幸的是,服务器不合作并返回 500 Internal Server Error
。也许它真的不接受 gzip
编码的请求?
或者我的方法有误?好像比较绕。有没有更简单的方法来使用 python-requests
进行请求正文压缩?
编辑: 修复了@sigmavirus24 的 answer 中的 (3) 和 (5) (这些基本上只是我在简化代码以在此处发布时忽略的工件)。
最佳答案
Or perhaps there is a mistake in my approach?
坦率地说,我不确定您是如何得出您的方法的,但肯定有一种更简单的方法可以做到这一点。
首先,有几点:
files
参数构造了一个multipart/form-data
主体。因此,您正在压缩服务器可能不知道的内容。Content-Encoding
和Transfer-Encoding
是两个截然不同的东西。您需要在此处使用Transfer-Encoding
。- 您不需要在
NamedTemporaryFile
上设置后缀。 - 由于您没有明确提到您正在尝试压缩
multipart/form-data
请求,因此我假设您实际上并不想这样做。 - 您对
session.Request
的调用(我假设应该是requests.Request
)缺少一个方法,即它应该是:requests。请求('POST', endpoint_url, ...)
有了这些,下面是我将如何做到这一点:
# Assuming `file` is a file-like obj
with NamedTemporaryFile(delete=True) as gzfile:
gzip.GzipFile(fileobj=gzfile, mode="wb").write(file.read())
headers = {'Content-Length': str(gzfile.tell()),
'Transfer-Encoding': 'gzip'}
gzfile.seek(0, 0)
response = session.post(endpoint_url, data=gzfile,
headers=headers)
假设 file
中有 xml
内容,而您的意思是压缩它,这应该适合您。你可能想要设置一个 Content-Type
header ,例如,你可以这样做
headers = {'Content-Length': gzfile.tell(),
'Content-Type': 'application/xml', # or 'text/xml'
'Transfer-Encoding': 'gzip'}
Transfer-Encoding
告诉服务器请求只在传输过程中被压缩,它应该解压它。 Content-Type
告诉服务器在处理完 Transfer-Encoding
后如何处理内容。
关于python - 使用 python-requests 压缩请求体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28656068/