| 30 | self.app = app |
| 31 | |
| 32 | def __call__(self, environ, start_response): |
| 33 | # The middleware sets a number of headers that helps prevent a range of attacks in browser |
| 34 | # environment. It also handles OPTIONS requests used by browser as pre-flight check before |
| 35 | # the potentially insecure request is made. An absence of this headers on the response will |
| 36 | # prevent the error from ever reaching the JS layer of client-side code making it impossible |
| 37 | # to process the response or provide a human-friendly error message. Order is not important |
| 38 | # as long at this condition is met and headers not get overridden by another middleware |
| 39 | # higher up the call stack. |
| 40 | request = Request(environ) |
| 41 | |
| 42 | def custom_start_response(status, headers, exc_info=None): |
| 43 | headers = ResponseHeaders(headers) |
| 44 | |
| 45 | origin = request.headers.get("Origin") |
| 46 | origins = OrderedSet(cfg.CONF.api.allow_origin) |
| 47 | |
| 48 | # Build a list of the default allowed origins |
| 49 | public_api_url = cfg.CONF.auth.api_url |
| 50 | |
| 51 | # Default gulp development server WebUI URL |
| 52 | origins.add("http://127.0.0.1:3000") |
| 53 | |
| 54 | # By default WebUI simple http server listens on 8080 |
| 55 | origins.add("http://localhost:8080") |
| 56 | origins.add("http://127.0.0.1:8080") |
| 57 | |
| 58 | if public_api_url: |
| 59 | # Public API URL |
| 60 | origins.add(public_api_url) |
| 61 | |
| 62 | origins = list(origins) |
| 63 | |
| 64 | if origin: |
| 65 | if "*" in origins: |
| 66 | origin_allowed = origin |
| 67 | else: |
| 68 | # See http://www.w3.org/TR/cors/#access-control-allow-origin-response-header |
| 69 | origin_allowed = origin if origin in origins else list(origins)[0] |
| 70 | else: |
| 71 | origin_allowed = list(origins)[0] |
| 72 | |
| 73 | methods_allowed = ["GET", "POST", "PUT", "DELETE", "OPTIONS"] |
| 74 | request_headers_allowed = [ |
| 75 | "Content-Type", |
| 76 | "Authorization", |
| 77 | HEADER_ATTRIBUTE_NAME, |
| 78 | HEADER_API_KEY_ATTRIBUTE_NAME, |
| 79 | REQUEST_ID_HEADER, |
| 80 | ] |
| 81 | response_headers_allowed = [ |
| 82 | "Content-Type", |
| 83 | "X-Limit", |
| 84 | "X-Total-Count", |
| 85 | REQUEST_ID_HEADER, |
| 86 | ] |
| 87 | |
| 88 | headers["Access-Control-Allow-Origin"] = origin_allowed |
| 89 | headers["Access-Control-Allow-Methods"] = ",".join(methods_allowed) |