Given some event_info via API Gateway, create and return a valid WSGI request environ.
(
event_info,
server_name="zappa",
script_name=None,
trailing_slash=True,
binary_support=False,
base_path=None,
context_header_mappings=None,
)
| 16 | |
| 17 | |
| 18 | def create_wsgi_request( |
| 19 | event_info, |
| 20 | server_name="zappa", |
| 21 | script_name=None, |
| 22 | trailing_slash=True, |
| 23 | binary_support=False, |
| 24 | base_path=None, |
| 25 | context_header_mappings=None, |
| 26 | ): |
| 27 | """ |
| 28 | Given some event_info via API Gateway, |
| 29 | create and return a valid WSGI request environ. |
| 30 | """ |
| 31 | if event_info.get("version", "") == "2.0": |
| 32 | method, headers, path, query_string, remote_user, authorizer = process_lambda_payload_v2(event_info) |
| 33 | else: |
| 34 | method, headers, path, query_string, remote_user, authorizer = process_lambda_payload_v1(event_info) |
| 35 | |
| 36 | resolve_context_headers(event_info, headers, context_header_mappings) |
| 37 | |
| 38 | # Related: https://github.com/Miserlou/Zappa/issues/677 |
| 39 | # https://github.com/Miserlou/Zappa/issues/683 |
| 40 | # https://github.com/Miserlou/Zappa/issues/696 |
| 41 | # https://github.com/Miserlou/Zappa/issues/836 |
| 42 | # https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Summary_table |
| 43 | body = extract_request_body(event_info, method, binary_support) |
| 44 | |
| 45 | # Make header names canonical, e.g. content-type => Content-Type |
| 46 | # https://github.com/Miserlou/Zappa/issues/1188 |
| 47 | headers = titlecase_keys(headers) |
| 48 | |
| 49 | if base_path: |
| 50 | script_name = f"/{base_path}" |
| 51 | |
| 52 | if path.startswith(script_name): |
| 53 | path = path[len(script_name) :] |
| 54 | |
| 55 | x_forwarded_for = headers.get("X-Forwarded-For", "") |
| 56 | if "," in x_forwarded_for: |
| 57 | # The last one is the cloudfront proxy ip. The second to last is the real client ip. |
| 58 | # Everything else is user supplied and untrustworthy. |
| 59 | addresses = [addr.strip() for addr in x_forwarded_for.split(",")] |
| 60 | remote_addr = addresses[-2] |
| 61 | else: |
| 62 | remote_addr = x_forwarded_for or "127.0.0.1" |
| 63 | |
| 64 | environ = { |
| 65 | "PATH_INFO": get_wsgi_string(path), |
| 66 | "QUERY_STRING": get_wsgi_string(query_string), |
| 67 | "REMOTE_ADDR": remote_addr, |
| 68 | "REQUEST_METHOD": method, |
| 69 | "SCRIPT_NAME": get_wsgi_string(str(script_name)) if script_name else "", |
| 70 | "SERVER_NAME": str(server_name), |
| 71 | "SERVER_PORT": headers.get("X-Forwarded-Port", "80"), |
| 72 | "SERVER_PROTOCOL": str("HTTP/1.1"), |
| 73 | "wsgi.version": (1, 0), |
| 74 | "wsgi.url_scheme": headers.get("X-Forwarded-Proto", "http"), |
| 75 | # This must be Bytes or None |