Skip to content

Commit 94a681e

Browse files
committed
Fix APIGW path with stage
APIGW HTTP has started adding the stage to the path in the event. This change checks if the stage is already a prefix in the path, and skips adding it if so. Signed-off-by: David Calavera <[email protected]>
1 parent f47d448 commit 94a681e

File tree

2 files changed

+89
-4
lines changed

2 files changed

+89
-4
lines changed

lambda-http/src/request.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,17 @@ fn into_websocket_request(ag: ApiGatewayWebsocketProxyRequest) -> http::Request<
327327

328328
#[cfg(any(feature = "apigw_rest", feature = "apigw_http", feature = "apigw_websockets"))]
329329
fn apigw_path_with_stage(stage: &Option<String>, path: &str) -> String {
330-
match stage {
331-
None => path.into(),
332-
Some(stage) if stage == "$default" => path.into(),
333-
Some(stage) => format!("/{stage}{path}"),
330+
let stage = match stage {
331+
None => return path.into(),
332+
Some(stage) if stage == "$default" => return path.into(),
333+
Some(stage) => stage,
334+
};
335+
336+
let prefix = format!("/{stage}/");
337+
if path.starts_with(&prefix) {
338+
path.into()
339+
} else {
340+
format!("/{stage}{path}")
334341
}
335342
}
336343

@@ -768,4 +775,25 @@ mod tests {
768775
let url = build_request_uri("/path with spaces/and multiple segments", &HeaderMap::new(), None, None);
769776
assert_eq!("/path%20with%20spaces/and%20multiple%20segments", url);
770777
}
778+
779+
#[test]
780+
fn deserializes_apigw_http_request_with_stage_in_path() {
781+
let input = include_str!("../tests/data/apigw_v2_proxy_request_with_stage_in_path.json");
782+
let result = from_str(input);
783+
assert!(
784+
result.is_ok(),
785+
"event was not parsed as expected {result:?} given {input}"
786+
);
787+
let req = result.expect("failed to parse request");
788+
assert_eq!("/Prod/my/path", req.uri().path());
789+
assert_eq!("/Prod/my/path", req.raw_http_path());
790+
}
791+
792+
#[test]
793+
fn test_apigw_path_with_stage() {
794+
assert_eq!("/path", apigw_path_with_stage(&None, "/path"));
795+
assert_eq!("/path", apigw_path_with_stage(&Some("$default".into()), "/path"));
796+
assert_eq!("/Prod/path", apigw_path_with_stage(&Some("Prod".into()), "/Prod/path"));
797+
assert_eq!("/Prod/path", apigw_path_with_stage(&Some("Prod".into()), "/path"));
798+
}
771799
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"version": "2.0",
3+
"routeKey": "Prod",
4+
"rawPath": "/Prod/my/path",
5+
"rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
6+
"cookies": [
7+
"cookie1=value1",
8+
"cookie2=value2"
9+
],
10+
"headers": {
11+
"Header1": "value1",
12+
"Header2": "value2"
13+
},
14+
"queryStringParameters": {
15+
"parameter1": "value1,value2",
16+
"parameter2": "value"
17+
},
18+
"requestContext": {
19+
"accountId": "123456789012",
20+
"apiId": "api-id",
21+
"authorizer": {
22+
"jwt": {
23+
"claims": {
24+
"claim1": "value1",
25+
"claim2": "value2"
26+
},
27+
"scopes": [
28+
"scope1",
29+
"scope2"
30+
]
31+
}
32+
},
33+
"domainName": "id.execute-api.us-east-1.amazonaws.com",
34+
"domainPrefix": "id",
35+
"http": {
36+
"method": "POST",
37+
"path": "/Prod/my/path",
38+
"protocol": "HTTP/1.1",
39+
"sourceIp": "IP",
40+
"userAgent": "agent"
41+
},
42+
"requestId": "id",
43+
"routeKey": "Prod",
44+
"stage": "Prod",
45+
"time": "12/Mar/2020:19:03:58 +0000",
46+
"timeEpoch": 1583348638390
47+
},
48+
"body": "Hello from Lambda",
49+
"pathParameters": {
50+
"parameter1": "value1"
51+
},
52+
"isBase64Encoded": false,
53+
"stageVariables": {
54+
"stageVariable1": "value1",
55+
"stageVariable2": "value2"
56+
}
57+
}

0 commit comments

Comments
 (0)