aws / aws-lambda-dotnet

Libraries, samples and tools to help .NET Core developers develop AWS Lambda functions.
Apache License 2.0
1.58k stars 475 forks source link

Lambda ASP NET Core Server is returning Content-Type Header even on NoContent Response #1123

Open dyeske61283 opened 2 years ago

dyeske61283 commented 2 years ago

Description

We are using Amazon.Lambda.AspNetCoreServer 6.0.3 and normal ASP Net Controllers and responses. The ActionResults for NoContent (HTTP 204) and Ok (HTTP 200) are correctly returning HTTP responses with a body and without a content-type header. The ApiGatewayProxyFunction transforms that result into the following: { "statusCode": 204, "headers": {}, "multiValueHeaders": { "Content-Type": [ null ] }, "body": "", "isBase64Encoded": false }

There is two Problems with this reponse:

  1. Content-Type can never be a multiValueHeader. The RFC (https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.2) states that.
  2. On 204 there should not even be a content-type header (and on 200 with an empty body, probably as well) See the RFC 7231 section 3.1.5.5 for that.

Reproduction Steps

Implement a simple GET Endpoint that returns either NoContent() or Ok() and call it e.g. via the AWS console and the Test Lambda Template for "apigateway-aws-proxy". The response should be similar to the one above.

Environment

Resolution

The error should be in APIGatewayProxyFunction.MarshallResponse lines 202 and following. Content-Type will need to be written to the Headers collection, but only if there is actually content in the response.


This is a :bug: bug-report

batwad commented 1 month ago

Is there a fix for this? I am being bitten by this issue at the moment.

The response from the my Lambda function looks like this:

{
  "statusCode": 200,
  "headers": {},
  "multiValueHeaders": {
    "Content-Type": [
      null
    ]
  },
  "body": "",
  "isBase64Encoded": false
}

This is a result of returning an empty OK response in a minimal API:

return Results.Ok();

@dyeske61283 the commit 2e08207 you reference checks whether body is null, but in this case it's coming as an empty string so the dodgy Content-Type header is still generated.

dyeske61283 commented 1 month ago

Hey @batwad This was some while ago, but I think what we did as a workaround was actively return Ok("") - an empty string. Other then that, there was sadly no fix. I tried implementing a fix myself - therefore the referenced commit - but this one has other issue with it. (e.g. as you also noted with the content coming in as an empty string for example)

batwad commented 1 month ago

Ha, my workaround was similar - although I couldn't change the response payload I added the following code to forcibly return a Content-Type header which kept the calling client happy.

        context.Response.ContentType = MediaTypeNames.Application.Json;

For future reference, the calling client is Kong and it is invoking the Lambda function directly pretending to be API Gateway which is quite neat: https://github.com/Kong/kong/tree/master/kong/plugins/aws-lambda

dyeske61283 commented 1 month ago

Funnily enough, we had the exact same use case, where the error came up. We also used Kong as the API GW to invoke the Lambdas.