def cors_enforced_fetch(client, request, callback=None, **kwargs): request = normalize_request(request, **kwargs) preflight, checks = prepare_preflight(request) if preflight is not None: preflight = HTTPRequest(preflight.url, preflight.method, preflight.headers) response = yield safe_fetch(client.fetch, preflight) if response.error: raise AccessControlError("Pre-flight check failed", preflight.url, preflight.method, preflight.headers) # check that the preflight response says its ok to send our followup. # below check again that the preflight grants access to the response. for check in checks: check(response, request) response = yield safe_fetch(client.fetch, request) # double-check that the actual response included appropriate headers as well # skip checks in the case of a server error unless configured otherwise. skip_checks = getattr(client, "skip_checks_on_server_error", False) if response.code / 100 != 5 or not skip_checks: check_origin(response, request) # wrap the headers in a protective layer exposed = response.headers.get("Access-Control-Expose-Headers", "") response.headers = ProtectedHTTPHeaders(exposed, response.headers) if not callable(callback): raise Return(response) else: callback(response)
def setUp(self): self.headers = { "Content-Length": "20", "Foo-Bar": "foobar", "Content-Type": "application/json" } self.protected = ProtectedHTTPHeaders(("foo-bar", "x-auth-token"), self.headers)
def test_initialize_with_header_string(self): protected = ProtectedHTTPHeaders("foo-bar, x-auth-token", self.headers) self.assertEqual(protected["foo-bar"], "foobar") with self.assertRaises(AccessControlError) as context: _ = protected["Content-Length"] self.assertIn("not allowed", context.exception.message)
def send(request, session=None, skip_checks_on_server_error=True, **kwargs): """ Send a request adhering to same-origin policy rules. Heads up; this function uses the requests library because most people do. If you intend to use another Python HTTP client, don't use this method """ session = session or requests.Session() preflight, checks = prepare_preflight(request) if preflight is not None: preflight = requests.Request(preflight.method, preflight.url, preflight.headers, **preflight.kwargs).prepare() response = session.send(preflight) if not response.ok: raise AccessControlError( "Pre-flight check failed. Response status: %s: %s, Headers: %s" % (response.status_code, response.reason, response.headers), preflight.url, preflight.method, preflight.headers) # check that the preflight response says its ok to send our followup. # below check again that the preflight grants access to the response. for check in checks: check(response, request) response = session.send(request, **kwargs) # double-check that the actual response included appropriate headers as well # skip checks in the case of a server error unless configured otherwise. if response.status_code / 100 != 5 or not skip_checks_on_server_error: check_origin(response, request) # wrap the headers in a protective layer exposed = response.headers.get("Access-Control-Expose-Headers", "") response.headers = ProtectedHTTPHeaders(exposed, response.headers) return response