Skip to content

Commit

Permalink
fix: return correct header keys for each integration (#877)
Browse files Browse the repository at this point in the history
Each integration handle header keys differently, this patch tries to
address these differences so that we have proper headers in responses.

**ALB Integration**
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers-response

    The names of the fields used for headers differ depending on
    whether you enable multi-value headers for the target group.
    You must use multiValueHeaders if you have enabled multi-value
    headers and headers otherwise.

**APIGW v1 Integration**
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format

    If you specify values for both headers and multiValueHeaders,
    API Gateway merges them into a single list. If the same key-value
    pair is specified in both, only the values from multiValueHeaders
    will appear in the merged list.

**APIGW v2 Integration**
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html

    Format 2.0 doesn't have multiValueHeaders or
    multiValueQueryStringParameters fields. Duplicate headers are
    combined with commas and included in the headers field.
    Duplicate query strings are combined with commas and included
    in the queryStringParameters field.

**`awslabs/aws-lambda-go-api-proxy` source code**

- https://github.com/awslabs/aws-lambda-go-api-proxy/blob/3f6c8160ae0c22b0bd05b2e3a9122736f035c74b/core/response.go#L117
- https://github.com/awslabs/aws-lambda-go-api-proxy/blob/3f6c8160ae0c22b0bd05b2e3a9122736f035c74b/core/responseALB.go#L108
- https://github.com/awslabs/aws-lambda-go-api-proxy/blob/3f6c8160ae0c22b0bd05b2e3a9122736f035c74b/core/responsev2.go#L117
  • Loading branch information
fluxth authored May 17, 2024
1 parent 343159e commit 447d9fb
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions lambda-http/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ impl LambdaResponse {
body,
is_base64_encoded,
status_code: status_code as i64,
// explicitly empty, as API gateway does not properly merge headers and
// multi-value-headers, resulting in duplicate headers
// Explicitly empty, as API gateway v1 will merge "headers" and
// "multi_value_headers" fields together resulting in duplicate response headers.
headers: HeaderMap::new(),
multi_value_headers: headers,
}),
Expand All @@ -93,21 +93,20 @@ impl LambdaResponse {
is_base64_encoded,
status_code: status_code as i64,
cookies,
// explicitly empty, as API gateway does not properly merge headers and
// multi-value-headers, resulting in duplicate headers
headers: HeaderMap::new(),
multi_value_headers: headers,
// API gateway v2 doesn't have "multi_value_headers" field. Duplicate headers
// are combined with commas and included in the headers field.
headers,
multi_value_headers: HeaderMap::new(),
})
}
#[cfg(feature = "alb")]
RequestOrigin::Alb => LambdaResponse::Alb(AlbTargetGroupResponse {
body,
status_code: status_code as i64,
is_base64_encoded,
// ALB responses are used for ALB integrations as well as
// Lambda Function URLs. The former uses the `multi_value_headers` field,
// while the later uses the `headers` field. We need to return
// both fields to ensure both integrations work correctly.
// ALB responses are used for ALB integration, which can be configured to use
// either "headers" or "multi_value_headers" field. We need to return both fields
// to ensure both configuration work correctly.
headers: headers.clone(),
multi_value_headers: headers,
status_description: Some(format!(
Expand All @@ -121,8 +120,8 @@ impl LambdaResponse {
body,
is_base64_encoded,
status_code: status_code as i64,
// explicitly empty, as API gateway does not properly merge headers and
// multi-value-headers, resulting in duplicate headers
// Explicitly empty, as API gateway v1 will merge "headers" and
// "multi_value_headers" fields together resulting in duplicate response headers.
headers: HeaderMap::new(),
multi_value_headers: headers,
}),
Expand Down Expand Up @@ -475,7 +474,7 @@ mod tests {
let json = serde_json::to_string(&response).expect("failed to serialize to json");
assert_eq!(
json,
r#"{"statusCode":200,"headers":{},"multiValueHeaders":{"content-encoding":["gzip"]},"body":"MDAwMDAw","isBase64Encoded":true,"cookies":[]}"#
r#"{"statusCode":200,"headers":{"content-encoding":"gzip"},"multiValueHeaders":{},"body":"MDAwMDAw","isBase64Encoded":true,"cookies":[]}"#
)
}

Expand All @@ -493,7 +492,7 @@ mod tests {
let json = serde_json::to_string(&response).expect("failed to serialize to json");
assert_eq!(
json,
r#"{"statusCode":200,"headers":{},"multiValueHeaders":{"content-type":["application/json"]},"body":"000000","isBase64Encoded":false,"cookies":[]}"#
r#"{"statusCode":200,"headers":{"content-type":"application/json"},"multiValueHeaders":{},"body":"000000","isBase64Encoded":false,"cookies":[]}"#
)
}

Expand All @@ -511,7 +510,7 @@ mod tests {
let json = serde_json::to_string(&response).expect("failed to serialize to json");
assert_eq!(
json,
r#"{"statusCode":200,"headers":{},"multiValueHeaders":{"content-type":["application/json; charset=utf-16"]},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"#
r#"{"statusCode":200,"headers":{"content-type":"application/json; charset=utf-16"},"multiValueHeaders":{},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"#
)
}

Expand All @@ -529,7 +528,7 @@ mod tests {
let json = serde_json::to_string(&response).expect("failed to serialize to json");
assert_eq!(
json,
r#"{"statusCode":200,"headers":{},"multiValueHeaders":{"content-type":["application/graphql-response+json; charset=utf-16"]},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"#
r#"{"statusCode":200,"headers":{"content-type":"application/graphql-response+json; charset=utf-16"},"multiValueHeaders":{},"body":"〰〰〰","isBase64Encoded":false,"cookies":[]}"#
)
}

Expand Down

0 comments on commit 447d9fb

Please sign in to comment.