Skip to content

Instantly share code, notes, and snippets.

@mocobeta
Created August 21, 2012 15:03
Show Gist options
  • Save mocobeta/3416291 to your computer and use it in GitHub Desktop.
Save mocobeta/3416291 to your computer and use it in GitHub Desktop.
リクエストパラメータでエンコーディングを切り替えるWSGI Middleware
#-*- coding: utf-8 -*-
ENCODINGS = ["utf-8", "sjis"]
CHARSET = {"utf-8": "UTF-8", "sjis": "Shift_JIS"}
class EncodingHandlerMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, env, start_response):
import urlparse
qs = env['QUERY_STRING']
try:
# クエリ文字列を辞書に変換
params = urlparse.parse_qs(qs)
# さらに辞書中の値をすべてデコードして、envに入れ込む
# envに入れ込むのは、(もちろん)アプリから使えるようにするため
d_params = self.decode_params(params)
env["QDICT"] = d_params
# アプリ呼び出し
res = self.app(env, start_response)
# レスポンスをエンコード
(res_enc, res) = self.encode_response(params, res)
# レスポンスのエンコードに合わせてContent-typeのcharsetを切り替える
content_type = "text/plain; charset=%s" % CHARSET[res_enc]
start_response("200 OK", [("Content-type", content_type)])
return [res]
except Exception:
start_response("500 Internal Server Error", [("Content-type", "text/plain")])
return ["Error. Maybe invalid encoding?"]
def decode_params(self, params):
"""
req_encパラメータを見て,辞書内の値をデコードする
"""
req_enc = params.get("req_enc", ["utf-8"])[0]
if req_enc not in ENCODINGS:
req_enc = "utf-8"
print "request encoding: " + req_enc
d = {}
for key, vals in params.items():
decoded = []
# クエリパラメータ値をすべてデコードし、あらためて辞書に格納
for v in vals:
v = v.decode(req_enc)
decoded.append(v)
d[key] = decoded
return d
def encode_response(self, params, res):
"""
res_encパラメータを見て,Unicode文字列をエンコードする
"""
res_enc = params.get("res_enc", ["utf-8"])[0]
if res_enc not in ENCODINGS:
res_enc = "utf-8"
print "response encoding: " + res_enc
return (res_enc, res.encode(res_enc))
def application(env, start_response):
# アプリ内では、Unicode文字列のみ扱う
d_params = env["QDICT"]
# 何か処理. ここではクエリパラメータをそのまま返しているだけ.
input = d_params.get("input", [])
res = " ".join(input)
return res
if __name__ == "__main__":
from wsgiref import simple_server
app = EncodingHandlerMiddleware(application)
srv = simple_server.make_server("", 8080, app)
srv.serve_forever()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment