Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,7 @@ venv.bak/

# IDE Settings
.idea/
.vscode
.devcontainer

.DS_Store
5 changes: 4 additions & 1 deletion mangum/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from mangum.protocols import HTTPCycle, LifespanCycle
from mangum.handlers import ALB, HTTPGateway, APIGateway, LambdaAtEdge
from mangum.handlers.utils import DEFAULT_TEXT_MIME_TYPES
Comment thread
jordaneremieff marked this conversation as resolved.
Outdated
from mangum.exceptions import ConfigurationError
from mangum.types import (
ASGI,
Expand Down Expand Up @@ -34,6 +35,7 @@ def __init__(
lifespan: LifespanMode = "auto",
api_gateway_base_path: str = "/",
custom_handlers: Optional[List[Type[LambdaHandler]]] = None,
text_mime_types: Optional[List[str]] = None,
) -> None:
if lifespan not in ("auto", "on", "off"):
raise ConfigurationError(
Expand All @@ -45,6 +47,7 @@ def __init__(
self.api_gateway_base_path = api_gateway_base_path or "/"
self.config = LambdaConfig(api_gateway_base_path=self.api_gateway_base_path)
self.custom_handlers = custom_handlers or []
self.text_mime_types = text_mime_types or DEFAULT_TEXT_MIME_TYPES

def infer(self, event: LambdaEvent, context: LambdaContext) -> LambdaHandler:
for handler_cls in chain(self.custom_handlers, HANDLERS):
Expand All @@ -71,6 +74,6 @@ def __call__(self, event: LambdaEvent, context: LambdaContext) -> dict:
http_cycle = HTTPCycle(handler.scope, handler.body)
http_response = http_cycle(self.app)

return handler(http_response)
return handler(http_response, self.text_mime_types)
Comment thread
jordaneremieff marked this conversation as resolved.
Outdated

assert False, "unreachable" # pragma: no cover
10 changes: 7 additions & 3 deletions mangum/handlers/alb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from itertools import islice
from typing import Dict, Generator, List, Tuple
from typing import Dict, Generator, List, Optional, Tuple
from urllib.parse import urlencode, unquote, unquote_plus

from mangum.handlers.utils import (
Expand Down Expand Up @@ -143,7 +143,11 @@ def scope(self) -> Scope:

return scope

def __call__(self, response: Response) -> dict:
def __call__(
self,
response: Response,
text_mime_types: Optional[List[str]] = None,
) -> dict:
multi_value_headers: Dict[str, List[str]] = {}
for key, value in response["headers"]:
lower_key = key.decode().lower()
Expand All @@ -153,7 +157,7 @@ def __call__(self, response: Response) -> dict:

finalized_headers = case_mutated_headers(multi_value_headers)
finalized_body, is_base64_encoded = handle_base64_response_body(
response["body"], finalized_headers
response["body"], finalized_headers, text_mime_types
)

out = {
Expand Down
20 changes: 14 additions & 6 deletions mangum/handlers/api_gateway.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, List, Tuple
from typing import Dict, List, Optional, Tuple
from urllib.parse import urlencode

from mangum.handlers.utils import (
Expand Down Expand Up @@ -110,12 +110,16 @@ def scope(self) -> Scope:
"aws.context": self.context,
}

def __call__(self, response: Response) -> dict:
def __call__(
self,
response: Response,
text_mime_types: Optional[List[str]] = None,
) -> dict:
finalized_headers, multi_value_headers = handle_multi_value_headers(
response["headers"]
)
finalized_body, is_base64_encoded = handle_base64_response_body(
response["body"], finalized_headers
response["body"], finalized_headers, text_mime_types
)

return {
Expand Down Expand Up @@ -196,15 +200,19 @@ def scope(self) -> Scope:
"aws.context": self.context,
}

def __call__(self, response: Response) -> dict:
def __call__(
self,
response: Response,
text_mime_types: Optional[List[str]] = None,
) -> dict:
if self.scope["aws.event"]["version"] == "2.0":
finalized_headers, cookies = _combine_headers_v2(response["headers"])

if "content-type" not in finalized_headers and response["body"] is not None:
finalized_headers["content-type"] = "application/json"

finalized_body, is_base64_encoded = handle_base64_response_body(
response["body"], finalized_headers
response["body"], finalized_headers, text_mime_types
)
response_out = {
"statusCode": response["status"],
Expand All @@ -221,7 +229,7 @@ def __call__(self, response: Response) -> dict:
response["headers"]
)
finalized_body, is_base64_encoded = handle_base64_response_body(
response["body"], finalized_headers
response["body"], finalized_headers, text_mime_types
)
return {
"statusCode": response["status"],
Expand Down
10 changes: 7 additions & 3 deletions mangum/handlers/lambda_at_edge.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, List
from typing import Dict, List, Optional

from mangum.handlers.utils import (
handle_base64_response_body,
Expand Down Expand Up @@ -76,10 +76,14 @@ def scope(self) -> Scope:
"aws.context": self.context,
}

def __call__(self, response: Response) -> dict:
def __call__(
self,
response: Response,
text_mime_types: Optional[List[str]] = None,
) -> dict:
multi_value_headers, _ = handle_multi_value_headers(response["headers"])
response_body, is_base64_encoded = handle_base64_response_body(
response["body"], multi_value_headers
response["body"], multi_value_headers, text_mime_types
)
finalized_headers: Dict[str, List[Dict[str, str]]] = {
key.decode().lower(): [{"key": key.decode().lower(), "value": val.decode()}]
Expand Down
8 changes: 5 additions & 3 deletions mangum/handlers/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import base64
from typing import Dict, List, Tuple, Union
from typing import Dict, List, Optional, Tuple, Union
from urllib.parse import unquote

from mangum.types import Headers
Expand Down Expand Up @@ -71,12 +71,14 @@ def handle_multi_value_headers(


def handle_base64_response_body(
body: bytes, headers: Dict[str, str]
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 DEFAULT_TEXT_MIME_TYPES:
for text_mime_type in text_mime_types or DEFAULT_TEXT_MIME_TYPES:
Comment thread
jordaneremieff marked this conversation as resolved.
Outdated
if text_mime_type in headers.get("content-type", ""):
try:
output_body = body.decode()
Expand Down
6 changes: 5 additions & 1 deletion mangum/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,9 @@ def body(self) -> bytes:
def scope(self) -> Scope:
... # pragma: no cover

def __call__(self, response: Response) -> dict:
def __call__(
self,
response: Response,
text_mime_types: Optional[List[str]] = None,
) -> dict:
... # pragma: no cover