From 0bd6005cb9dc3232ec6904c3e18af8ca09ba4953 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Sat, 7 Jun 2014 00:26:11 +0200 Subject: [PATCH] API: Allow cross-origin requests When a REST API is called from within a browser page from a different domain, the server needs to explicitly allow this. This makes the OctoPrint API available also to other webapps, for instance those hosted on same network in hackerspace. --- src/octoprint/server/api/__init__.py | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/octoprint/server/api/__init__.py b/src/octoprint/server/api/__init__.py index 6524bf41..c384b56c 100644 --- a/src/octoprint/server/api/__init__.py +++ b/src/octoprint/server/api/__init__.py @@ -32,6 +32,28 @@ from . import users as api_users from . import log as api_logs +def optionsAllowOrigin(request): + """ Always reply 200 on OPTIONS request """ + + resp = current_app.make_default_options_response() + + headers = None + if 'ACCESS_CONTROL_REQUEST_HEADERS' in request.headers: + headers = request.headers['ACCESS_CONTROL_REQUEST_HEADERS'] + + # Allow the origin which made the XHR + resp.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] + # Allow the actual method + resp.headers['Access-Control-Allow-Methods'] = request.headers['Access-Control-Request-Method'] + # Allow for 10 seconds + resp.headers['Access-Control-Max-Age'] = "10" + + # We also keep current headers + if headers is not None: + resp.headers['Access-Control-Allow-Headers'] = headers + + return resp + @api.before_request def beforeApiRequests(): """ @@ -41,6 +63,9 @@ def beforeApiRequests(): the request. """ + if request.method == 'OPTIONS': + return optionsAllowOrigin(request) + apikey = getApiKey(request) if apikey is None: # no api key => 401 @@ -66,6 +91,16 @@ def beforeApiRequests(): # invalid api key => 401 return make_response("Invalid API key", 401) +@api.after_request +def afterApiRequests(resp): + """""" + + # Allow crossdomain + if request.method != 'OPTIONS' and 'Origin' in request.headers: + resp.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] + + return resp + #~~ first run setup