Skip to content

Commit

Permalink
fix(start-api): Accept non-integer statusCode JSON values (aws#1013)
Browse files Browse the repository at this point in the history
  • Loading branch information
slank authored and jfuss committed Feb 19, 2019
1 parent 73a1569 commit b34386d
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 1 deletion.
6 changes: 5 additions & 1 deletion samcli/local/apigw/local_apigw_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,11 @@ def _parse_lambda_output(lambda_output, binary_types, flask_request):
body = json_output.get("body") or "no data"
is_base_64_encoded = json_output.get("isBase64Encoded") or False

if not isinstance(status_code, int) or status_code <= 0:
try:
status_code = int(status_code)
if status_code <= 0:
raise ValueError
except ValueError:
message = "statusCode must be a positive int"
LOG.error(message)
raise TypeError(message)
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/local/start_api/test_start_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ def test_default_status_code(self):
self.assertEquals(response.status_code, 200)
self.assertEquals(response.json(), {'hello': 'world'})

def test_string_status_code(self):
"""
Test that an integer-string can be returned as the status code
"""
response = requests.get(self.url + "/stringstatuscode")

self.assertEquals(response.status_code, 200)

def test_default_body(self):
"""
Test that if no body is given, the response is 'no data'
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/testdata/start_api/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def only_set_body_handler(event, context):
return {"body": json.dumps({"hello": "world"})}


def string_status_code_handler(event, context):

return {"statusCode": "200", "body": json.dumps({"hello": "world"})}


def sleep_10_sec_handler(event, context):
# sleep thread for 10s. This is useful for testing multiple requests
time.sleep(10)
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/testdata/start_api/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ Resources:
Method: Get
Path: /onlysetbody

StringStatusCodeFunction:
Type: AWS::Serverless::Function
Properties:
Handler: main.string_status_code_handler
Runtime: python3.6
CodeUri: .
Events:
StringStatusCodePath:
Type: Api
Properties:
Method: Get
Path: /stringstatuscode

SleepFunction0:
Type: AWS::Serverless::Function
Properties:
Expand Down
18 changes: 18 additions & 0 deletions tests/unit/local/apigw/test_local_apigw_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,15 @@ def test_status_code_not_int(self):
binary_types=[],
flask_request=Mock())

def test_status_code_int_str(self):
lambda_output = '{"statusCode": "200", "headers": {}, "body": "{\\"message\\":\\"Hello from Lambda\\"}", ' \
'"isBase64Encoded": false}'

(status_code, _, _) = LocalApigwService._parse_lambda_output(lambda_output,
binary_types=[],
flask_request=Mock())
self.assertEquals(status_code, 200)

def test_status_code_negative_int(self):
lambda_output = '{"statusCode": -1, "headers": {}, "body": "{\\"message\\":\\"Hello from Lambda\\"}", ' \
'"isBase64Encoded": false}'
Expand All @@ -350,6 +359,15 @@ def test_status_code_negative_int(self):
binary_types=[],
flask_request=Mock())

def test_status_code_negative_int_str(self):
lambda_output = '{"statusCode": "-1", "headers": {}, "body": "{\\"message\\":\\"Hello from Lambda\\"}", ' \
'"isBase64Encoded": false}'

with self.assertRaises(TypeError):
LocalApigwService._parse_lambda_output(lambda_output,
binary_types=[],
flask_request=Mock())

def test_lambda_output_list_not_dict(self):
lambda_output = '[]'

Expand Down

0 comments on commit b34386d

Please sign in to comment.