Bottle/Python - "IOError: [Errno 9] read() on write-only GzipFile object" when trying to decompress request body
Bottle/Python - "IOError: [Errno 9] read() on write-only GzipFile object" when trying to decompress request body
我使用 Bottle 接收 gzipped 请求正文。当请求的大小很小时,一切都很好。但是,如果请求正文的大小稍大(例如,>= 20kb),则会抛出 IOError。
下面是读取并解压请求体的代码:
@post("/receive")
def receive():
try:
f = request.body
g_f = gzip.GzipFile(fileobj=f)
content = g_f.read()
# other stuff on the content...
except IOError, e:
# handle the error
错误信息是:
[2015-09-07 16:27:27,967][ERROR ] Failed to decompress gzipped data: [Errno 9] read() on write-only GzipFile object
127.0.0.1 - - [07/Sep/2015 16:27:27] "POST /receive HTTP/1.1" 400 756
这个问题是由于继承了用于创建GzipFile
对象的fileobj的read/write模式造成的。
如果 request.body
的大小小于 20k,Bottle
将整个二进制数据加载为 StringIO
对象。 GzipFile
处理 StringIO
很好,一切正常。
另一方面,如果 request.body
的大小大于 20k,Bottle
将使用 tempfile
模块为此请求主体创建一个临时文件,用于平台-consistency,tempfile
创建的文件默认模式是'w+b'。
但是,GzipFile判断一个文件是否可读只能通过hasattr(fileobj, 'mode')
得到的模式字符串,如果这个字符串是类似'rxx'的,GzipFile
认为它是可读的,反之亦然。如果调用不可读 GzipFile
的 read()
函数,将抛出 IOError
。
由于 GzipFile
将使用的文件模式是 'w+b',GzipFile
仍将其视为 'non-readable',因此,繁荣!抛出错误。要解决此问题,只需在创建 GzipFile
对象时添加 mode
参数:
try:
f = request.body
g_f = gzip.GzipFile(fileobj=f, mode='rb')
content = g_f.read()
# other stuff on the content...
except IOError, e:
# handle the error
我使用 Bottle 接收 gzipped 请求正文。当请求的大小很小时,一切都很好。但是,如果请求正文的大小稍大(例如,>= 20kb),则会抛出 IOError。
下面是读取并解压请求体的代码:
@post("/receive")
def receive():
try:
f = request.body
g_f = gzip.GzipFile(fileobj=f)
content = g_f.read()
# other stuff on the content...
except IOError, e:
# handle the error
错误信息是:
[2015-09-07 16:27:27,967][ERROR ] Failed to decompress gzipped data: [Errno 9] read() on write-only GzipFile object
127.0.0.1 - - [07/Sep/2015 16:27:27] "POST /receive HTTP/1.1" 400 756
这个问题是由于继承了用于创建GzipFile
对象的fileobj的read/write模式造成的。
如果 request.body
的大小小于 20k,Bottle
将整个二进制数据加载为 StringIO
对象。 GzipFile
处理 StringIO
很好,一切正常。
另一方面,如果 request.body
的大小大于 20k,Bottle
将使用 tempfile
模块为此请求主体创建一个临时文件,用于平台-consistency,tempfile
创建的文件默认模式是'w+b'。
但是,GzipFile判断一个文件是否可读只能通过hasattr(fileobj, 'mode')
得到的模式字符串,如果这个字符串是类似'rxx'的,GzipFile
认为它是可读的,反之亦然。如果调用不可读 GzipFile
的 read()
函数,将抛出 IOError
。
由于 GzipFile
将使用的文件模式是 'w+b',GzipFile
仍将其视为 'non-readable',因此,繁荣!抛出错误。要解决此问题,只需在创建 GzipFile
对象时添加 mode
参数:
try:
f = request.body
g_f = gzip.GzipFile(fileobj=f, mode='rb')
content = g_f.read()
# other stuff on the content...
except IOError, e:
# handle the error