【问题标题】:How to use gzip encoding with wsgi application?如何在 wsgi 应用程序中使用 gzip 编码?
【发布时间】:2014-03-01 12:26:09
【问题描述】:

我正在尝试使用 wsgi 输出 gzip 编码的字符串,这些是我的尝试,但不幸的是浏览器只解码了第一个字符串,有什么帮助吗?

测试 1:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    data += zlib.compress(b'test')[:-4]
    data += zlib.compress(b'test2')[:-4]
    headers.append(('Content-Length', str(len(data))))
    start_response('200 OK',headers)
    return [data]

测试 2:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    data = b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    data += zlib.compress(b'test')
    data += zlib.compress(b'test2')
    headers.append(('Content-Length', str(len(data))))
    start_response('200 OK',headers)
    return [data]

测试 3:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    start_response('200 OK',headers)
    yield b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    yield zlib.compress(b'test')[:-4]
    yield zlib.compress(b'test2')[:-4]

测试 4:

import zlib

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    start_response('200 OK',headers)
    yield b'\x1f\x8b\x08\x00\x00\x00\x00\x00'
    yield zlib.compress(b'test')
    yield zlib.compress(b'test2')

测试 5:

import gzip

def application(environ, start_response):
    headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
    start_response('200 OK',headers)
    yield gzip.compress(b'test')
    yield gzip.compress(b'test2')

【问题讨论】:

  • 那么问题是什么 - 为什么 test1 有效而其他无效?
  • @mockinterface 只是上面示例中解码的第一个,我的答案见下文。

标签: python python-3.x compression gzip wsgi


【解决方案1】:

我认为问题如下:

 gzip.compress(b'test')

返回一个字符串
 header  content  THE END 

在里面。

这意味着当您阅读它时,解压缩只会返回 b'test'。自己试试吧。

两种解决方案取决于您想要实现的目标:

  1. 创建多部分消息。每个收益都是一个新文档
  2. compress 这样做:

    def compress(data, compresslevel=9):
    
        """Compress data in one shot and return the compressed string.
        Optional argument is the compression level, in range of 0-9.
        """
        buf = io.BytesIO()
        with GzipFile(fileobj=buf, mode='wb', compresslevel=compresslevel) as f:
            f.write(data)
        return buf.getvalue()
    

    做这样的事情:

    import gzip, io
    
    def application(environ, start_response):
        headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding',     'gzip')]
        start_response('200 OK',headers)
        buf = io.BytesIO()
        with GzipFile(fileobj=buf, mode='wb') as f:
             f.write(b'test')
             f.write(b'test2')
        return buf
    

【讨论】:

    【解决方案2】:

    感谢@User,这是我自己使用的解决方案,我想我们不会在这里缓冲大量数据:

    import gzip
    
    class gzipreader:
        def __init__(self):
            self._content = b''
    
        def flush(self):
            pass
    
        def write(self,data):
            self._content += data
    
        def read(self):
            data = self._content
            self._content = b''
            return data
    
    def application(environ, start_response):
        headers = [('Content-Type', 'text/html; charset=utf-8'),('Content-Encoding', 'gzip')]
        start_response('200 OK',headers)
        reader = gzipreader()
        writer = gzip.GzipFile(mode='wb',fileobj=reader)
        for s in [b'test', b'test2']:
            writer.write(s)
            #writer.flush()
            yield reader.read()
        writer.close()
        yield reader.read()
    

    【讨论】:

    • 您不需要实现阅读器。 Python2下可以使用from StringIO import StringIO as gzipreader,Python3下可以使用from io import BytesIO as gzipreader
    • @User 它的工作方式不同,对我来说没有输出。
    • 对,您可能无法在此处使用 read。当您需要内存中的文件时,请记住该模块。对不起。
    猜你喜欢
    • 2015-01-17
    • 2014-04-04
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2016-03-28
    • 1970-01-01
    相关资源
    最近更新 更多