Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OPTIONS endpoint does not invoke lambda code #1434

Closed
caspian154 opened this issue Sep 27, 2019 · 10 comments
Closed

OPTIONS endpoint does not invoke lambda code #1434

caspian154 opened this issue Sep 27, 2019 · 10 comments
Labels
area/local/start-api sam local start-api command stage/waiting-for-release Fix has been merged to develop and is waiting for a release type/bug

Comments

@caspian154
Copy link

caspian154 commented Sep 27, 2019

Description

We have implemented OPTIONS endpoints that do some CORS related processes. With the release of version 0.20.0 the OPTIONS endpoints return 200 without invoking the lambda functions.

Steps to reproduce

  1. Start the api with sam local start-api -p 3002
  2. hit the endpoint with method OPTIONS http://localhost:3002/api/hello
  3. hit the endpoint with method GET http://localhost:3002/api/hello

Observed result

Using SAM Template at C:\development\centimark\hello-simple\options\template.yaml
Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
local start-api command is called
Collected default values for parameters: {'ENV': 'dev'}
2 resources found in the template
Found Serverless function with name='HelloWorldFunction' and CodeUri='hello/'
Collected default values for parameters: {'ENV': 'dev'}
2 resources found in the template
Detected Inline Swagger definition
Lambda function integration not found in Swagger document at path='/api/hello' method='options'
Lambda function integration not found in Swagger document at path='/api/hello' method='get'
Lambda function integration not found in Swagger document at path='/api/hello/{name}' method='get'
Found '0' APIs in resource 'ServerlessApi'
Found '3' API Events in Serverless function with name 'HelloWorldFunction'
Removed duplicates from '3' Explicit APIs and '0' Implicit APIs to produce '3' APIs
2 APIs found in the template
Mounting HelloWorldFunction at http://127.0.0.1:3002/api/hello [GET, OPTIONS]
Mounting HelloWorldFunction at http://127.0.0.1:3002/api/hello/{name} [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
Localhost server is starting up. Multi-threading = True
2019-09-27 16:20:58  * Running on http://127.0.0.1:3002/ (Press CTRL+C to quit)
2019-09-27 16:21:09 127.0.0.1 - - [27/Sep/2019 16:21:09] "OPTIONS /api/hello HTTP/1.1" 200 -
Constructed String representation of Event to invoke Lambda. Event: {"httpMethod": "GET", "body": null, "resource": "/api/hello", "requestContext": {"resourceId": "123456", "apiId": "1234567890", "resourcePath": "/api/hello", "httpMethod": "GET", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "accountId": "123456789012", "stage": "dev", "identity": {"apiKey": null, "userArn": null, "cognitoAuthenticationType": null, "caller": null, "userAgent": "Custom User Agent String", "user": null, "cognitoIdentityPoolId": null, "cognitoAuthenticationProvider": null, "sourceIp": "127.0.0.1", "accountId": null}, "extendedRequestId": null, "path": "/api/hello"}, "queryStringParameters": null, "multiValueQueryStringParameters": null, "headers": {"User-Agent": "PostmanRuntime/7.17.1", "Accept": "*/*", "Cache-Control": "no-cache", "Postman-Token": "9200a05a-495d-41e6-8135-bfb0a60f6be1", "Host": "localhost:3002", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "X-Forwarded-Proto": "http", "X-Forwarded-Port": "3002"}, "multiValueHeaders": {"User-Agent": ["PostmanRuntime/7.17.1"], "Accept": ["*/*"], "Cache-Control": ["no-cache"], "Postman-Token": ["9200a05a-495d-41e6-8135-bfb0a60f6be1"], "Host": ["localhost:3002"], "Accept-Encoding": ["gzip, deflate"], "Connection": ["keep-alive"], "X-Forwarded-Proto": ["http"], "X-Forwarded-Port": ["3002"]}, "pathParameters": null, "stageVariables": null, "path": "/api/hello", "isBase64Encoded": false}
Found one Lambda function with name 'HelloWorldFunction'
Invoking app.lambdaHandler (nodejs10.x)
Environment variables overrides data is standard format
Loading AWS credentials from session with profile 'None'
2019-09-27 16:21:31 Found credentials in shared credentials file: ~/.aws/credentials
Resolving code path. Cwd=C:\development\centimark\hello-simple\options, CodeUri=hello/
Resolved absolute path to code is C:\development\centimark\hello-simple\options\hello
Code C:\development\centimark\hello-simple\options\hello is not a zip/jar file
Skipping building an image since no layers were defined

Fetching lambci/lambda:nodejs10.x Docker container image......
Mounting C:\development\centimark\hello-simple\options\hello as /var/task:ro,delegated inside runtime container
Starting a timer for 3 seconds for function 'HelloWorldFunction'
?[32mSTART RequestId: 4b1797c8-6428-19d4-3401-e55eced3e107 Version: $LATEST?[0m
2019-09-27T20:21:33.456Z        4b1797c8-6428-19d4-3401-e55eced3e107    INFO    invoked hello world { httpMe  isBase64Encoded: false } '3002' ] },te' ],8135-bfb0a60f6be1' ],
?[32mEND RequestId: 4b1797c8-6428-19d4-3401-e55eced3e107?[0m
?[32mREPORT RequestId: 4b1797c8-6428-19d4-3401-e55eced3e107     Duration: 16.15 ms      Billed Duration: 100 ms     Memory Size: 128 MB     Max Memory Used: 42 MB  ?[0m
No Content-Type given. Defaulting to 'application/json'.
2019-09-27 16:21:34 127.0.0.1 - - [27/Sep/2019 16:21:34] "GET /api/hello HTTP/1.1" 200 -

Expected result

The expectation was that "invoked hello world" would be printed twice - once for the OPTIONS and once for the GET request.

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

  1. OS: Windows
  2. sam --version:
    SAM CLI, version 0.22.0

More details

Template File

Transform: AWS::Serverless-2016-10-31
Description: >
  The API gateway definition

Globals:
  Function:
    Timeout: 3

Parameters:
  ENV:
    Type: String
    Default: dev

Resources:

  ServerlessApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref ENV

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello/
      Handler: app.lambdaHandler
      Runtime: nodejs10.x
      Environment:
        Variables:
          ENV: !Ref ENV
      Events:
        HelloOptions:
          Type: Api
          Properties:
            RestApiId: !Ref ServerlessApi
            Path: /api/hello
            Method: options
        HelloWorld:
          Type: Api
          Properties:
            RestApiId: !Ref ServerlessApi
            Path: /api/hello
            Method: get
        HelloName:
          Type: Api
          Properties:
            RestApiId: !Ref ServerlessApi
            Path: /api/hello/{name}
            Method: get

hello/app.js


exports.lambdaHandler = async (event, context) => {
  let name = 'world';

  console.log(`invoked hello world`, event);

  if (event.pathParameters && event.pathParameters.name) {
    name = event.pathParameters.name;
  }

  try {
    response = {
      'statusCode': 200,
      'body': JSON.stringify({
        message: 'Hello ' + name,
        name
      })
    }
  } catch (err) {
    console.log(err);
    return err;
  }

  return response;
};
@awood45 awood45 added area/local/start-api sam local start-api command stage/needs-investigation Requires a deeper investigation labels Sep 30, 2019
@awood45
Copy link
Member

awood45 commented Sep 30, 2019

Looking into this - for some background, have you tried this on Lambda as well and seen a different result?

@caspian154
Copy link
Author

@awood45 this is only an issue running sam local. When the template is run through cloudformation the api gateway properly invokes our Lambda. This is only an issue with testing locally - which is still a serious issue.

@caspian154
Copy link
Author

@awood45 should this ticket be in https://github.com/awslabs/serverless-application-model/issues I was just trying to find this issue in that repo and realized there is aws-sam-cli and servereless-application-model

@gordonmleigh
Copy link

As far as I can see the problem was introduced by #1242. In particular, the following added lines short-circuit all OPTIONS requests to the CORS behaviour.

https://github.com/awslabs/aws-sam-cli/blob/4cdd4076d688d8699ca9b87584c8fa59799a20b5/samcli/local/apigw/local_apigw_service.py#L176-L179

@gordonmleigh
Copy link

@awood45 I've got a fix over on #1464, just need a little help getting it over the line.

gordonmleigh pushed a commit to gordonmleigh/aws-sam-cli that referenced this issue Oct 22, 2019
douglasnaphas pushed a commit to douglasnaphas/aws-sam-cli that referenced this issue Dec 9, 2019
douglasnaphas added a commit to douglasnaphas/aws-sam-cli that referenced this issue Feb 6, 2020
aws#1434

This is intended to get the following integration tests passing:

tests/integration/local/start_api/test_start_api.py
  TestServiceCorsSwaggerRequests
  TestServiceCorsGlobalRequests

Those tests use a
[CorsConfiguration](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-api-corsconfiguration.html)
and a [Cors
Global](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html),
respectively, to enable CORS.

When CORS is enabled, OPTIONS requests should send a 200 with the
specified CORS headers, even if no OPTIONS handler is explicitly stated
in the pre-transformation SAM template. I confirmed this by deploying
from a [SAM
template](https://github.com/douglasnaphas/play-sam/tree/master/cors-swagger)
similar to one of the failing integration tests (with Cors specified but
with no explicit OPTIONS handler), and observing that it does indeed
respond with a 200 and the CORS headers attached.
douglasnaphas added a commit to douglasnaphas/aws-sam-cli that referenced this issue Feb 6, 2020
aws#1434

This is intended to get the following integration tests passing:

tests/integration/local/start_api/test_start_api.py
  TestServiceCorsSwaggerRequests
  TestServiceCorsGlobalRequests

Those tests use a
[CorsConfiguration](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-api-corsconfiguration.html)
and a [Cors
Global](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html),
respectively, to enable CORS.

When CORS is enabled, OPTIONS requests should send a 200 with the
specified CORS headers, even if no OPTIONS handler is explicitly stated
in the pre-transformation SAM template. I confirmed this by deploying
from a [SAM
template](https://github.com/douglasnaphas/play-sam/tree/master/cors-swagger)
similar to one of the failing integration tests (with Cors specified but
with no explicit OPTIONS handler), and observing that it does indeed
respond with a 200 and the CORS headers attached.
douglasnaphas pushed a commit to douglasnaphas/aws-sam-cli that referenced this issue Feb 6, 2020
douglasnaphas added a commit to douglasnaphas/aws-sam-cli that referenced this issue Feb 6, 2020
aws#1434

This is intended to get the following integration tests passing:

tests/integration/local/start_api/test_start_api.py
  TestServiceCorsSwaggerRequests
  TestServiceCorsGlobalRequests

Those tests use a
[CorsConfiguration](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-api-corsconfiguration.html)
and a [Cors
Global](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html),
respectively, to enable CORS.

When CORS is enabled, OPTIONS requests should send a 200 with the
specified CORS headers, even if no OPTIONS handler is explicitly stated
in the pre-transformation SAM template. I confirmed this by deploying
from a [SAM
template](https://github.com/douglasnaphas/play-sam/tree/master/cors-swagger)
similar to one of the failing integration tests (with Cors specified but
with no explicit OPTIONS handler), and observing that it does indeed
respond with a 200 and the CORS headers attached.
@douglasnaphas
Copy link
Contributor

@awood45 I've got a fix over on #1464, just need a little help getting it over the line.

@gordonmleigh I pulled your commits into #1649 and was able to get the integration tests passing in that PR.

douglasnaphas referenced this issue in douglasnaphas/play-sam Feb 18, 2020
douglasnaphas/aws-sam-cli#1

To see the problem with OPTIONS described in this Issue:

  1. Make one directory where the branch for the PR addressing the issue
is checked out, from the awslabs/aws-sam-cli repo (the PR dir).
  1. Make another directory where the develop branch of the
awslabs/aws-sam-cli repo is checked out (the develop dir).
  1. In each of the above two dirs, activate a virtualenv for Python
3.7.4 and run `make init` to make a `samdev` executable available in
each virtualenv.
  1. In the PR dir, run `samdev local start-api --profile $PROFILE
--template $PLAY-SAM/dev-template.yml --port 5000 --host
localhost`
  1. In the develop dir, run `samdev local start-api --profile $PROFILE
--template $PLAY-SAM/dev-template.yml --port 5001 --host
localhost`
  1. In each dir, run `curl -X OPTIONS -i http://localhost:$PORT` where
`$PORT` is 5000 or 5001, depending on the dir.
  1. You should get a 200 with `"Output":"hello from options"}` as the
response data from the Express server in the PR dir, 200 with no data in
the develop dir. This illustrates the issue of OPTIONS not reaching the
handler.
douglasnaphas added a commit to douglasnaphas/aws-sam-cli that referenced this issue Feb 18, 2020
aws#1434

This adds an integration test to verify that templates with explicit
OPTIONS handlers actually have those handlers invoked on OPTIONS
requests. There has been an issue with OPTIONS requests returning 200
and not reaching an explicitly specified OPTIONS handler.
aws#1649 fixes that, so if the
integration test added in this commit passes (and fails on the develop
branch), it could be added to that PR.
douglasnaphas added a commit to douglasnaphas/aws-sam-cli that referenced this issue Feb 18, 2020
aws#1434

This adds an integration test to verify that templates with explicit
OPTIONS handlers actually have those handlers invoked on OPTIONS
requests. There has been an issue with OPTIONS requests returning 200
and not reaching an explicitly specified OPTIONS handler.
aws#1649 fixes that, so if the
integration test added in this commit passes (and fails on the develop
branch), it could be added to that PR.
@jfuss jfuss added type/bug and removed stage/needs-investigation Requires a deeper investigation labels Feb 19, 2020
@jfuss jfuss added the stage/waiting-for-release Fix has been merged to develop and is waiting for a release label Feb 19, 2020
@jfuss
Copy link
Contributor

jfuss commented Feb 21, 2020

Was released in v0.42.0.

Closing

@jfuss jfuss closed this as completed Feb 21, 2020
@diegoddox
Copy link

Not sure if I should create a new issue for it but I'm facing this on version 1.83.0

@diegoddox
Copy link

diegoddox commented Nov 5, 2023

Any update on this? still facing this issue on v1.100.0

@rpcsp
Copy link

rpcsp commented May 16, 2024

Facing this issue too with v1.103.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/local/start-api sam local start-api command stage/waiting-for-release Fix has been merged to develop and is waiting for a release type/bug
Projects
None yet
Development

No branches or pull requests

7 participants