-
-
Notifications
You must be signed in to change notification settings - Fork 130
Expand file tree
/
Copy pathutils.py
More file actions
93 lines (75 loc) · 2.8 KB
/
utils.py
File metadata and controls
93 lines (75 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import base64
from typing import Dict, List, Optional, Tuple, Union
from urllib.parse import unquote
from mangum.types import Headers
DEFAULT_TEXT_MIME_TYPES = [
"text/",
"application/json",
"application/javascript",
"application/xml",
"application/vnd.api+json",
"application/vnd.oai.openapi",
]
def maybe_encode_body(body: Union[str, bytes], *, is_base64: bool) -> bytes:
body = body or b""
if is_base64:
body = base64.b64decode(body)
elif not isinstance(body, bytes):
body = body.encode()
return body
def get_server_and_port(headers: dict) -> Tuple[str, int]:
server_name = headers.get("host", "mangum")
if ":" not in server_name:
server_port = headers.get("x-forwarded-port", 80)
else:
server_name, server_port = server_name.split(":") # pragma: no cover
server = (server_name, int(server_port))
return server
def strip_api_gateway_path(path: str, *, api_gateway_base_path: str) -> str:
if not path:
return "/"
if api_gateway_base_path and api_gateway_base_path != "/":
if not api_gateway_base_path.startswith("/"):
api_gateway_base_path = f"/{api_gateway_base_path}"
if path.startswith(api_gateway_base_path):
path = path[len(api_gateway_base_path) :]
return unquote(path)
def handle_multi_value_headers(
response_headers: Headers,
) -> Tuple[Dict[str, str], Dict[str, List[str]]]:
headers: Dict[str, str] = {}
multi_value_headers: Dict[str, List[str]] = {}
for key, value in response_headers:
lower_key = key.decode().lower()
if lower_key in multi_value_headers:
multi_value_headers[lower_key].append(value.decode())
elif lower_key in headers:
# Move existing to multi_value_headers and append current
multi_value_headers[lower_key] = [
headers[lower_key],
value.decode(),
]
del headers[lower_key]
else:
headers[lower_key] = value.decode()
return headers, multi_value_headers
def handle_base64_response_body(
body: bytes,
headers: Dict[str, str],
text_mime_types: Optional[List[str]] = None,
) -> Tuple[str, bool]:
is_base64_encoded = False
output_body = ""
if body != b"":
for text_mime_type in text_mime_types or DEFAULT_TEXT_MIME_TYPES:
if text_mime_type in headers.get("content-type", ""):
try:
output_body = body.decode()
except UnicodeDecodeError:
output_body = base64.b64encode(body).decode()
is_base64_encoded = True
break
else:
output_body = base64.b64encode(body).decode()
is_base64_encoded = True
return output_body, is_base64_encoded