Bottle / Python - " IOError:[Errno 9] read()on write-only GzipFile object"当试图解压缩请求体

时间:2015-09-07 08:37:13

标签: python gzip bottle

我使用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

1 个答案:

答案 0 :(得分:3)

此问题是由用于创建GzipFile对象的fileobj的读/写模式的继承引起的。

如果request.body的大小小于20k,Bottle会将整个二进制数据作为StringIO对象加载。 GzipFile很好地处理StringIO,一切正常。

另一方面,如果request.body的大小大于20k,Bottle将使用tempfile模块为此请求正文创建临时文件,以实现平台一致性,tempfile创建的默认文件模式为“w + b”。

但是,GzipFile通过hasattr(fileobj, 'mode')获取的模式字符串确定文件是否可读,如果此字符串类似于'rxx',GzipFile认为它是可读的,反之亦然。如果调用了不可读read()的{​​{1}}函数,则会抛出GzipFile

由于IOError将使用的文件模式为'w + b',GzipFile仍然会将其视为'不可读',因此,繁荣!抛出错误。要解决此问题,只需在创建GzipFile对象时添加mode参数:

GzipFile