encode("zlib")でwsgiアプリをdeflate対応させる

strのメソッドencode()やdecode()では、"utf-8"などの文字コードだけじゃなく"base64"、"zlib"、"bz2"、"uu"、"hex"、"rot13"といったものもつかえるようです(/usr/lib/python2.6/encodings/以下にある)。でもなぜか"gzip"はありません。

encode("zlib")をつかって以下のようにすることで、wsgiアプリをdeflate対応にできます。

#!/usr/bin/env python
# -*- coding: utf-8 mode: python -*-

def application(env, start_response):
    status = "200 OK"
    headers = [("Content-Type", "text/html;charset=UTF-8")]
    deflate = "deflate" in env.get("HTTP_ACCEPT_ENCODING", "").split(",")

    content = "<html><body>"
    content += "Hello %s" % ("deflate" if deflate else "identity")
    content += "</body></html>"

    if deflate:
        headers.append(("Content-Encoding", "deflate"))
        content = content.encode("zlib")
        pass
    start_response(status, headers)
    return [content]

if __name__ == "__main__":
    from wsgiref.handlers import CGIHandler
    CGIHandler().run(application)
    pass

decoratorにもできますね

def deflatable(app):
    def deflator(env, start_res):
        deflate = "deflate" in env.get("HTTP_ACCEPT_ENCODING", "").split(",")
        def start_wrapper(status, headers):
            headers.append(("Content-Encoding", "deflate"))
            return start_res(status, headers)
        contents = app(env, start_wrapper if deflate else start_res)
        return ["".join(contents).encode("zlib")] if deflate else contents
    return deflator

@deflatable
def application(env, start_response):
   ...