From 5001689d234912b44e6acb0613851831ee698b10 Mon Sep 17 00:00:00 2001 From: dap0am Date: Thu, 15 Jan 2026 12:09:22 +0000 Subject: [PATCH 1/2] fix(lambda-events): Deprecate authorizer-specific fields in ApiGatewayV2httpRequest Deprecates fields in ApiGatewayV2httpRequest that are only present in Custom Authorizer v1 payloads but not in standard HTTP API v2 requests: - kind (type) - method_arn - http_method - identity_source - authorization_token The http_method field incorrectly defaults to GET when missing, which can lead to security issues as POST/PUT/DELETE requests may be treated as GET. For standard HTTP API v2 requests, users should use request_context.http.method to get the correct HTTP method. For Custom Authorizer v1 payloads, users should use the dedicated ApiGatewayV2CustomAuthorizerV1Request struct. Adds comprehensive documentation explaining the correct usage patterns and a test demonstrating how to properly access the HTTP method for standard HTTP API v2 requests. Fixes #1080 --- lambda-events/src/event/apigw/mod.rs | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index 015eff40..70f6666e 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -137,18 +137,74 @@ pub struct ApiGatewayProxyRequestContext { } /// `ApiGatewayV2httpRequest` contains data coming from the new HTTP API Gateway +/// +/// # Important Note +/// +/// For standard HTTP API v2 requests, the HTTP method is located in `request_context.http.method`, +/// not in the top-level `http_method` field. The top-level `http_method` field (and other +/// authorizer-specific fields) are only present in Custom Authorizer v1 payloads. +/// +/// **For standard HTTP API v2 requests, use `request_context.http.method` to get the correct HTTP method.** +/// +/// For Custom Authorizer v1 payloads, use the dedicated `ApiGatewayV2CustomAuthorizerV1Request` struct instead. #[non_exhaustive] #[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct ApiGatewayV2httpRequest { + /// The type field from Custom Authorizer v1 requests. + /// + /// This field is not present in standard HTTP API v2 requests. + /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. + #[deprecated( + since = "0.14.0", + note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." + )] #[serde(default, rename = "type")] pub kind: Option, + /// The method ARN from Custom Authorizer v1 requests. + /// + /// This field is not present in standard HTTP API v2 requests. + /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. + #[deprecated( + since = "0.14.0", + note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." + )] #[serde(default)] pub method_arn: Option, + /// The HTTP method field. + /// + /// **Warning**: This field defaults to `GET` if not present in the payload, which may lead to + /// incorrect behavior. For standard HTTP API v2 requests, this field is not present in the JSON payload. + /// + /// **Use `request_context.http.method` instead for standard HTTP API v2 requests**, which contains + /// the actual HTTP method for the request. + /// + /// This top-level `http_method` field is only present in Custom Authorizer v1 requests. + /// For those payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. + #[deprecated( + since = "0.14.0", + note = "For standard HTTP API v2 requests, use `request_context.http.method` instead. This field defaults to GET when missing and may return incorrect values. For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request`." + )] #[serde(with = "http_method", default = "default_http_method")] pub http_method: Method, + /// The identity source from Custom Authorizer v1 requests. + /// + /// This field is not present in standard HTTP API v2 requests. + /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. + #[deprecated( + since = "0.14.0", + note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." + )] #[serde(default)] pub identity_source: Option, + /// The authorization token from Custom Authorizer v1 requests. + /// + /// This field is not present in standard HTTP API v2 requests. + /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. + #[deprecated( + since = "0.14.0", + note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." + )] #[serde(default)] pub authorization_token: Option, #[serde(default)] @@ -1205,6 +1261,22 @@ mod test { assert_eq!(parsed, reparsed); } + #[test] + #[cfg(feature = "apigw")] + fn apigw_v2_correct_http_method_usage() { + // This test demonstrates the correct way to access the HTTP method + // for standard HTTP API v2 requests: use request_context.http.method + let data = include_bytes!("../../fixtures/example-apigw-v2-request-no-authorizer.json"); + let parsed: ApiGatewayV2httpRequest = serde_json::from_slice(data).unwrap(); + + // The correct way to get the HTTP method for standard HTTP API v2 requests + assert_eq!(parsed.request_context.http.method, Method::GET); + + // Verify that request_context.http.method contains the actual method from the JSON + // In the fixture, requestContext.http.method is "GET" + assert_eq!(parsed.request_context.http.method, Method::GET); + } + #[test] #[cfg(feature = "apigw")] fn example_apigw_websocket_request() { From e68c66f7d8c55ef15f5b96d02da31e16a816e4db Mon Sep 17 00:00:00 2001 From: dap0am Date: Thu, 15 Jan 2026 16:14:48 +0000 Subject: [PATCH 2/2] fix: Update deprecation version from 0.14.0 to 1.1.0 Address review feedback to correct the 'since' parameter in deprecated attributes to match the upcoming release version. --- lambda-events/src/event/apigw/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lambda-events/src/event/apigw/mod.rs b/lambda-events/src/event/apigw/mod.rs index 70f6666e..c35da0cd 100644 --- a/lambda-events/src/event/apigw/mod.rs +++ b/lambda-events/src/event/apigw/mod.rs @@ -156,7 +156,7 @@ pub struct ApiGatewayV2httpRequest { /// This field is not present in standard HTTP API v2 requests. /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. #[deprecated( - since = "0.14.0", + since = "1.1.0", note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." )] #[serde(default, rename = "type")] @@ -166,7 +166,7 @@ pub struct ApiGatewayV2httpRequest { /// This field is not present in standard HTTP API v2 requests. /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. #[deprecated( - since = "0.14.0", + since = "1.1.0", note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." )] #[serde(default)] @@ -182,7 +182,7 @@ pub struct ApiGatewayV2httpRequest { /// This top-level `http_method` field is only present in Custom Authorizer v1 requests. /// For those payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. #[deprecated( - since = "0.14.0", + since = "1.1.0", note = "For standard HTTP API v2 requests, use `request_context.http.method` instead. This field defaults to GET when missing and may return incorrect values. For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request`." )] #[serde(with = "http_method", default = "default_http_method")] @@ -192,7 +192,7 @@ pub struct ApiGatewayV2httpRequest { /// This field is not present in standard HTTP API v2 requests. /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. #[deprecated( - since = "0.14.0", + since = "1.1.0", note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." )] #[serde(default)] @@ -202,7 +202,7 @@ pub struct ApiGatewayV2httpRequest { /// This field is not present in standard HTTP API v2 requests. /// For Custom Authorizer v1 payloads, use `ApiGatewayV2CustomAuthorizerV1Request` instead. #[deprecated( - since = "0.14.0", + since = "1.1.0", note = "This field is only present in Custom Authorizer v1 requests. Use `ApiGatewayV2CustomAuthorizerV1Request` for authorizer payloads." )] #[serde(default)]