Skip to content

Commit 2721e16

Browse files
authored
fix: http uri parsing (#161)
1 parent 6528a78 commit 2721e16

File tree

6 files changed

+62
-1
lines changed

6 files changed

+62
-1
lines changed

src/lumigo_tracer/lumigo_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,7 @@ def get_size_upper_bound() -> int:
544544

545545
def is_error_code(status_code: int) -> bool:
546546
return status_code >= 400
547+
548+
549+
def is_aws_arn(string_to_validate: Optional[str]) -> bool:
550+
return bool(string_to_validate and string_to_validate.startswith("arn:aws:"))

src/lumigo_tracer/parsing_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,7 @@ def recursive_get_key(d: Union[List, Dict[str, Union[Dict, str]]], key, depth=No
187187
if recursive_result:
188188
return recursive_result
189189
return default
190+
191+
192+
def extract_function_name_from_arn(arn: str) -> str:
193+
return safe_split_get(arn, ":", 6)

src/lumigo_tracer/wrappers/http/http_parser.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import uuid
33
from typing import Type, Optional
4+
from urllib.parse import unquote
45

56
from lumigo_tracer.parsing_utils import (
67
safe_split_get,
@@ -10,6 +11,7 @@
1011
recursive_json_join,
1112
safe_get,
1213
should_scrub_domain,
14+
extract_function_name_from_arn,
1315
)
1416
from lumigo_tracer.lumigo_utils import (
1517
Configuration,
@@ -18,6 +20,7 @@
1820
get_logger,
1921
get_current_ms_time,
2022
is_error_code,
23+
is_aws_arn,
2124
)
2225
from lumigo_tracer.wrappers.http.http_data_classes import HttpRequest
2326

@@ -170,9 +173,14 @@ def parse_response(self, url: str, status_code: int, headers, body: bytes) -> di
170173

171174
class LambdaParser(ServerlessAWSParser):
172175
def parse_request(self, parse_params: HttpRequest) -> dict:
176+
decoded_uri = safe_split_get(unquote(parse_params.uri), "/", 3)
173177
return recursive_json_join(
174178
{
175-
"info": {"resourceName": safe_split_get(parse_params.uri, "/", 3)},
179+
"info": {
180+
"resourceName": extract_function_name_from_arn(decoded_uri)
181+
if is_aws_arn(decoded_uri)
182+
else decoded_uri
183+
},
176184
"invocationType": parse_params.headers.get("x-amz-invocation-type"),
177185
},
178186
super().parse_request(parse_params),

src/test/unit/test_lumigo_utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
KILL_SWITCH,
3434
is_error_code,
3535
get_size_upper_bound,
36+
is_aws_arn,
3637
)
3738
import json
3839

@@ -409,3 +410,15 @@ def test_get_size_upper_bound():
409410
)
410411
def test_is_error_code(status_code, is_error):
411412
assert is_error_code(status_code) is is_error
413+
414+
415+
@pytest.mark.parametrize(
416+
("arn", "is_arn_result"),
417+
[
418+
("not-arn", False),
419+
(None, False),
420+
("arn:aws:lambda:region:876841109798:function:function-name", True),
421+
],
422+
)
423+
def test_is_aws_arn(arn, is_arn_result):
424+
assert is_aws_arn(arn) is is_arn_result

src/test/unit/test_parsing_utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
safe_key_from_query,
1515
safe_key_from_xml,
1616
safe_get_list,
17+
extract_function_name_from_arn,
1718
)
1819
from lumigo_tracer.lumigo_utils import config, Configuration
1920

@@ -169,3 +170,11 @@ def test_str_to_tuple():
169170

170171
def test_str_to_tuple_exception():
171172
assert str_to_tuple([1]) is None
173+
174+
175+
def test_extract_name_from_arn():
176+
name = "function-name"
177+
assert (
178+
extract_function_name_from_arn(f"arn:aws:lambda:region:123847209798:function:{name}")
179+
== name # noqa
180+
)

src/test/unit/wrappers/http/test_http_parser.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
ApiGatewayV2Parser,
1212
DynamoParser,
1313
EventBridgeParser,
14+
LambdaParser,
1415
)
1516

1617

@@ -76,6 +77,28 @@ def test_apigw_parse_response_with_aws_request_id():
7677
}
7778

7879

80+
@pytest.mark.parametrize(
81+
"uri, resource_name",
82+
[
83+
(
84+
"lambda.us-west-2.amazonaws.com/2015-03-31/functions/my-function/invocations?Qualifier=1",
85+
"my-function",
86+
),
87+
(
88+
"lambda.eu-central-1.amazonaws.com/2015-03-31/functions/arn%3Aaws%3Alambda%3Aeu-central-1%3A123847209798%3Afunction%3Aservice-prod-accessRedis/invocations",
89+
"service-prod-accessRedis",
90+
),
91+
],
92+
)
93+
def test_lambda_parser_resource_name(uri, resource_name):
94+
parser = LambdaParser()
95+
params = HttpRequest(
96+
host="", method="POST", uri=uri, headers={}, body=json.dumps({"hello": "world"})
97+
)
98+
response = parser.parse_request(params)
99+
assert response["info"]["resourceName"] == resource_name
100+
101+
79102
@pytest.mark.parametrize(
80103
"method, body, message_id",
81104
[

0 commit comments

Comments
 (0)