diff --git a/.autover/changes/7db9a194-0cc2-43e7-81da-e2f468d3fc90.json b/.autover/changes/7db9a194-0cc2-43e7-81da-e2f468d3fc90.json new file mode 100644 index 000000000..1375f0777 --- /dev/null +++ b/.autover/changes/7db9a194-0cc2-43e7-81da-e2f468d3fc90.json @@ -0,0 +1,11 @@ +{ + "Projects": [ + { + "Name": "Amazon.Lambda.AspNetCoreServer", + "Type": "Patch", + "ChangelogMessages": [ + "Fixed issue \u0027(EmptyBodyBehavior = EmptyBodyBehavior.Allow)\u0027 not being honored when request body was empty" + ] + } + ] +} \ No newline at end of file diff --git a/.autover/changes/f8f316e8-1393-4185-bfb1-07ccfa2e68bf.json b/.autover/changes/f8f316e8-1393-4185-bfb1-07ccfa2e68bf.json new file mode 100644 index 000000000..ac48a24ef --- /dev/null +++ b/.autover/changes/f8f316e8-1393-4185-bfb1-07ccfa2e68bf.json @@ -0,0 +1,11 @@ +{ + "Projects": [ + { + "Name": "Amazon.Lambda.AspNetCoreServer.Hosting", + "Type": "Patch", + "ChangelogMessages": [ + "Fixed issue \u0027(EmptyBodyBehavior = EmptyBodyBehavior.Allow)\u0027 not being honored when request body was empty" + ] + } + ] +} \ No newline at end of file diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/InvokeFeatures.cs b/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/InvokeFeatures.cs index 293f26b6a..c10da003b 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/InvokeFeatures.cs +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/Internal/InvokeFeatures.cs @@ -392,7 +392,7 @@ bool IHttpRequestBodyDetectionFeature.CanHaveBody get { var requestFeature = (IHttpRequestFeature)this; - return requestFeature.Body != null; + return requestFeature.Body != null && requestFeature.Body.Length > 0; } } diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/TestCallingWebAPI.cs b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/TestCallingWebAPI.cs index 658bd7f9b..8dd665967 100644 --- a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/TestCallingWebAPI.cs +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/TestCallingWebAPI.cs @@ -126,6 +126,15 @@ public async Task TestPutWithBody() Assert.Equal("text/plain; charset=utf-8", response.MultiValueHeaders["Content-Type"][0]); } + [Fact] + public async Task TestPutNoBody() + { + var response = await this.InvokeAPIGatewayRequest("values-put-no-body-request.json"); + + Assert.Equal(string.Empty, response.Body); + Assert.Equal(202, response.StatusCode); + } + [Fact] public async Task TestDefaultResponseErrorCode() { diff --git a/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/values-put-no-body-request.json b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/values-put-no-body-request.json new file mode 100644 index 000000000..9877ae200 --- /dev/null +++ b/Libraries/test/Amazon.Lambda.AspNetCoreServer.Test/values-put-no-body-request.json @@ -0,0 +1,65 @@ +{ + "resource": "/{proxy+}", + "path": "/api/values/no-body", + "httpMethod": "PUT", + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "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-ASN": "20055", + "CloudFront-Viewer-Country": "US", + "Host": "example.execute-api.us-west-2.amazonaws.com", + "User-Agent": "unittests", + "Via": "1.1 3dd55c11c72ef969f5e46a679c8244ba.cloudfront.net (CloudFront)", + "X-Amz-Cf-Id": "BA8bXHQfFrXacZsRsTUqvFLc849kUgSURcu8IkPIIadtNO2k6gMbtg==", + "X-Amzn-Trace-Id": "Root=1-67451657-4fdc56e47b7240b358e7ef09", + "X-Forwarded-For": "50.35.61.49, 3.172.20.16", + "X-Forwarded-Port": "443", + "X-Forwarded-Proto": "https", + "ContentLength": "0", + "Content-Type": "application/json" + }, + "queryStringParameters": null, + "multiValueQueryStringParameters": null, + "pathParameters": { + "proxy": "api/values/no-body" + }, + "stageVariables": null, + "requestContext": { + "resourceId": "3r2bn3", + "resourcePath": "/{proxy+}", + "httpMethod": "PUT", + "extendedRequestId": "B1BtwG20vHcEp-g=", + "requestTime": "26/Nov/2024:00:29:11 +0000", + "path": "/Prod/api/values/test", + "accountId": "111122223333", + "protocol": "HTTP/1.1", + "stage": "Prod", + "domainPrefix": "example", + "requestTimeEpoch": 1732580951687, + "requestId": "b5738763-be0a-4ded-945b-a92895dbc5de", + "identity": { + "cognitoIdentityPoolId": null, + "accountId": null, + "cognitoIdentityId": null, + "caller": null, + "sourceIp": "50.35.61.49", + "principalOrgId": null, + "accessKey": null, + "cognitoAuthenticationType": null, + "cognitoAuthenticationProvider": null, + "userArn": null, + "userAgent": "PostmanRuntime/7.42.0", + "user": null + }, + "domainName": "example.execute-api.us-west-2.amazonaws.com", + "deploymentId": "example", + "apiId": "example" + }, + "body": null, + "isBase64Encoded": false +} \ No newline at end of file diff --git a/Libraries/test/TestWebApp/Controllers/ValuesController.cs b/Libraries/test/TestWebApp/Controllers/ValuesController.cs index 3a96aeac3..87b675ebd 100644 --- a/Libraries/test/TestWebApp/Controllers/ValuesController.cs +++ b/Libraries/test/TestWebApp/Controllers/ValuesController.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ModelBinding; namespace TestWebApp.Controllers { @@ -49,5 +50,16 @@ public async Task ChectContentLength() return Content(sb.ToString()); } } + + [HttpPut("no-body")] + public IActionResult Test([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] Body request = default) + { + return Accepted(); + } + + public class Body + { + public string Prop { get; set; } + } } }