From 6126f0ec6f37ce5d06706e9b091e4a62ea54934a Mon Sep 17 00:00:00 2001 From: Martin Zimmermann Date: Tue, 5 Nov 2013 01:11:18 +0100 Subject: [PATCH] add CORS middleware to add CORS header to *all* requests --- isso/__init__.py | 19 +++++++++---------- isso/wsgi.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/isso/__init__.py b/isso/__init__.py index b5e43a9..7cfacd1 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -121,10 +121,6 @@ class Isso(object): | misaka.HTML_SKIP_HTML | misaka.HTML_SKIP_IMAGES | misaka.HTML_SAFELINK) def dispatch(self, request): - - if request.method == "OPTIONS": - return Isso.CORS(request, Response("", 200), self.conf.getiter("general", "host")) - adapter = Isso.urls.bind_to_environ(request.environ) try: @@ -139,8 +135,8 @@ class Isso(object): except Exception: logger.exception("%s %s", request.method, request.environ["PATH_INFO"]) return InternalServerError() - - return Isso.CORS(request, response, self.conf.getiter("general", "host")) + else: + return response def wsgi_app(self, environ, start_response): @@ -176,10 +172,13 @@ def make_app(conf=None): from werkzeug.contrib.profiler import ProfilerMiddleware isso = ProfilerMiddleware(isso, sort_by=("cumtime", ), restrictions=("isso/(?!lib)", )) - app = ProxyFix(wsgi.SubURI(SharedDataMiddleware(isso, { - '/js': join(dirname(__file__), 'js/'), - '/css': join(dirname(__file__), 'css/') - }))) + app = ProxyFix( + wsgi.SubURI( + wsgi.CORSMiddleWare( + SharedDataMiddleware(isso, { + '/js': join(dirname(__file__), 'js/'), + '/css': join(dirname(__file__), 'css/')}), + list(isso.conf.getiter("general", "host"))))) return app diff --git a/isso/wsgi.py b/isso/wsgi.py index b2cbf95..1ed6910 100644 --- a/isso/wsgi.py +++ b/isso/wsgi.py @@ -15,3 +15,33 @@ class SubURI(object): environ['PATH_INFO'] = path_info[len(script_name):] return self.app(environ, start_response) + + +class CORSMiddleWare(object): + + def __init__(self, app, hosts): + self.app = app + self.hosts = hosts + + def __call__(self, environ, start_response): + + def add_cors_headers(status, headers, exc_info=None): + + for host in self.hosts: + if environ.get("HTTP_ORIGIN", None) == host.rstrip("/"): + origin = host.rstrip("/") + break + else: + origin = host.rstrip("/") + + headers.append(("Access-Control-Allow-Origin", origin.encode("latin-1"))) + headers.append(("Access-Control-Allow-Headers", "Origin, Content-Type")) + headers.append(("Access-Control-Allow-Credentials", "true")) + headers.append(("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")) + return start_response(status, headers, exc_info) + + if environ.get("REQUEST_METHOD") == "OPTIONS": + add_cors_headers("200 Ok", [("Content-Type", "text/plain")]) + return ['200 Ok'] + + return self.app(environ, add_cors_headers)