Skip to content

Support for multiValueHeaders locally #830

@Sarke

Description

@Sarke

Description:
sam local start-api doesn't detect or pass along any of the multiValueHeaders from the lambda response.

This is most notable (for me) because it defaults to application/json content type even though another header is sent, so for example HTML will be displayed as plain text in the browser.

This is because it only checks the headers key in the lamba response, and not the multiValueHeaders key.

The code related to this issue is the _parse_lambda_output method, found here:
https://github.com/awslabs/aws-sam-cli/blob/develop/samcli/local/apigw/local_apigw_service.py#L182-L214

Here's an example lambda response (using https://github.com/stackery/php-lambda-layer).

{
  "body": "<html><body>test</body></html>",
  "multiValueHeaders": {
    "Connection": ["close"],
    "Content-type": ["text/html;charset=UTF-8"],
    "Date": ["Wed, 05 Dec 2018 00:51:05 +0000"],
    "Host": ["localhost:8000"],
    "X-Powered-By": ["PHP/7.1.7"]
    },
  "statusCode": 200
}

This works as expected once deployed, just not locally with sam.

See also:

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

https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#apigateway-multivalue-headers-and-parameters

Steps to reproduce the issue:

  1. Create template.yaml like this:
AWSTemplateFormatVersion: 2010-09-09
Description: PHP Lambda test
Transform: AWS::Serverless-2016-10-31
Resources:
  phpserver:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: phpserver
      Description: PHP Webserver
      CodeUri: src/php
      Runtime: provided
      Handler: index.php
      MemorySize: 256
      Timeout: 15
      Tracing: Active
      Layers:
        - 'arn:aws:lambda:us-west-2:887080169480:layer:php71:4'
      Events:
        api:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
  1. Create src/php/index.php with any content, e.g.:
<html><body>OK</body></html>
  1. Run sam local start-api and go to http://127.0.0.1:3000/test (or whatever the address).

Observed result:
None of the headers are sent to the browser. Content is displayed as plain text.

The response headers are:

Content-Type: application/json
Content-Length: 4
Server: Werkzeug/0.14.1 Python/2.7.15rc1
Date: Wed, 05 Dec 2018 00:28:36 GMT

Expected result:
sam local start-api detects the Content-Type header from the multiValueHeaders and the correct content type and other headers are sent to the browser. Content in this example is displayed properly as HTML.

Response headers similar to this, which is what I get from AWS once deployed:

content-type: text/html; charset=UTF-8
content-length: 4
date: Wed, 05 Dec 2018 01:36:09 GMT
x-powered-by: PHP/7.1.7

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
Linux

Output of sam --version:
SAM CLI, version 0.8.1

Optional Debug logs:

2018-12-04 17:41:24 No Content-Type given. Defaulting to 'application/json'.
2018-12-04 17:41:24 127.0.0.1 - - [04/Dec/2018 17:41:24] "GET /test HTTP/1.1" 200 -

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions