How do I get HTTP header 'Content-Length' in API Gateway Lambda Proxy integration

Viewed 1976

I need to build a function that takes 5 particular HTTP headers + the request params, aggregate, order, encode, and then hash them in order to validate/authenticate the overall request. However, I am unable to get the header 'Content-Length' to come through to the lambda.

I used Terraform to create the API Gateway (aws_api_gateway_domain_name) and then Serverless to create the endpoints:

functions:
  alerts:
    handler: src/event.handler
    role: arn:aws:iam::${env:AWS_ACCOUNT_ID}:role/alerts_lambda
    environment:
      API_TRANS_KEY: ${env:API_TRANS_KEY}
      REGION: ${self:custom.region}
      SNS_ARN: arn:aws:sns:us-east-1:${env:AWS_ACCOUNT_ID}:Transactions
      STAGE: ${self:custom.deploymentStage}
    events:
      - http:
          path: /alerts/AccountEvent
          method: post
          cors: true
          integration: lambda-proxy

however the headers I get are :

    "headers": {
        "Accept": "*/*",
        "accept-encoding": "gzip, deflate",
        "Cache-Control": "no-cache",
        "CloudFront-Forwarded-Proto": "https",
        "CloudFront-Is-Desktop-Viewer": "true",
        "CloudFront-Is-Mobile-Viewer": "false",
        "CloudFront-Is-SmartTV-Viewer": "false",
        "CloudFront-Is-Tablet-Viewer": "false",
        "CloudFront-Viewer-Country": "US",
        "Content-Type": "application/x-www-form-urlencoded",
        "Date": "20170504:141752UTC",
        "Encryption-Type": "HMAC-SHA256",
        "Host": "events.dev.myapi.com",
        "Postman-Token": "84bd0cc3-f339-4b2a-8017-31ec9174c37e",
        "User-Agent": "PostmanRuntime/7.11.0",
        "User-ID": "galileo",
        "Via": "1.1 50c3c79d5d7adbc8948ea11709b61d17.cloudfront.net (CloudFront)",
        "X-Amz-Cf-Id": "1OE1aGP_3Q-CkXFuJbRwvkGAR2ZaHAPuozckZ6747EP64zZcmXjphw==",
        "X-Amzn-Trace-Id": "Root=1-5d0bf01b-8afdb9628f42a9357dbb5c68",
        "X-Forwarded-For": "73.72.58.46, 70.132.57.87",
        "X-Forwarded-Port": "443",
        "X-Forwarded-Proto": "https"
    },

Do I need to use a mapping template at this point? Is CloudFront/Api Gateway stripping this header out for some reason (note, I don't set up a CloudFront distribution but API Gateway is creating one due to 'edge' type, but I could change it to 'regional' if that would solve this)?

2 Answers

Based on my tests, the Content-Length header can be passed through when making an API request. However, it won't appear in the event payload for a Lambda proxy integration.

Two alternatives that you could use to receive the Content-Length header:

  • Use an HTTP API with Lambda proxy integration instead of a REST API in API Gateway.

  • Use a Lambda non-proxy Integration for the REST API and configure it as follows:

    1. In the Mapping Templates for Integration Request:

      • Set application/json as the Content-Type
      • Change the default 'Method Passthrough Template' template by adding the statement - "X-Content-Length" : $input.body.length()
    2. In the Lambda function, the variable event ['X-Content-Length'] will contain the Content-Length.

Related