Created
August 21, 2012 15:03
-
-
Save mocobeta/3416291 to your computer and use it in GitHub Desktop.
リクエストパラメータでエンコーディングを切り替えるWSGI Middleware
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-*- 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