diff --git a/samcli/local/apigw/local_apigw_service.py b/samcli/local/apigw/local_apigw_service.py index c18304064a..7cef57d664 100644 --- a/samcli/local/apigw/local_apigw_service.py +++ b/samcli/local/apigw/local_apigw_service.py @@ -231,6 +231,7 @@ def _parse_lambda_output(lambda_output, binary_types, flask_request): :param str lambda_output: Output from Lambda Invoke :return: Tuple(int, dict, str, bool) """ + # pylint: disable-msg=too-many-statements json_output = json.loads(lambda_output) if not isinstance(json_output, dict): @@ -251,6 +252,14 @@ def _parse_lambda_output(lambda_output, binary_types, flask_request): LOG.error(message) raise TypeError(message) + try: + if body: + body = str(body) + except ValueError: + message = "Non null response bodies should be able to convert to string: {}".format(body) + LOG.error(message) + raise TypeError(message) + # API Gateway only accepts statusCode, body, headers, and isBase64Encoded in # a response shape. invalid_keys = LocalApigwService._invalid_apig_response_keys(json_output) diff --git a/tests/integration/local/start_api/test_start_api.py b/tests/integration/local/start_api/test_start_api.py index 84fbf2da79..4d4a7b2a69 100644 --- a/tests/integration/local/start_api/test_start_api.py +++ b/tests/integration/local/start_api/test_start_api.py @@ -479,6 +479,12 @@ def test_function_writing_to_stderr(self): self.assertEquals(response.status_code, 200) self.assertEquals(response.json(), {'hello': 'world'}) + def test_integer_body(self): + response = requests.get(self.url + "/echo_integer_body") + + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content.decode('utf-8'), '42') + class TestServiceRequests(StartApiIntegBaseClass): """ diff --git a/tests/integration/testdata/start_api/main.py b/tests/integration/testdata/start_api/main.py index 7e3875cdfc..fc6bc06482 100644 --- a/tests/integration/testdata/start_api/main.py +++ b/tests/integration/testdata/start_api/main.py @@ -4,39 +4,36 @@ def handler(event, context): - return {"statusCode": 200, "body": json.dumps({"hello": "world"})} def echo_event_handler(event, context): - return {"statusCode": 200, "body": json.dumps(event)} def echo_event_handler_2(event, context): - event['handler'] = 'echo_event_handler_2' return {"statusCode": 200, "body": json.dumps(event)} -def content_type_setter_handler(event, context): +def echo_integer_body(event, context): + return {"statusCode": 200, "body": 42} + +def content_type_setter_handler(event, context): return {"statusCode": 200, "body": "hello", "headers": {"Content-Type": "text/plain"}} def only_set_status_code_handler(event, context): - return {"statusCode": 200} 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"})} diff --git a/tests/integration/testdata/start_api/template.yaml b/tests/integration/testdata/start_api/template.yaml index d9786fb52f..763009613a 100644 --- a/tests/integration/testdata/start_api/template.yaml +++ b/tests/integration/testdata/start_api/template.yaml @@ -73,6 +73,19 @@ Resources: Method: GET Path: /echoeventbody + EchoIntegerBodyFunction: + Type: AWS::Serverless::Function + Properties: + Handler: main.echo_integer_body + Runtime: python3.6 + CodeUri: . + Events: + EchoEventBodyPath: + Type: Api + Properties: + Method: GET + Path: /echo_integer_body + ContentTypeSetterFunction: Type: AWS::Serverless::Function Properties: