-
Notifications
You must be signed in to change notification settings - Fork 475
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
Doubled response when using Amazon.Lambda.AspNetCoreServer.Hosting with .Net 6 Minimal API with custom endpoints extension #1108
Comments
the double response writing behavior is caused by the fact that using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]
var builder = WebApplication.CreateBuilder();
builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);
var app = builder.Build();
app.MapGet("/test", async (HttpContext ctx) =>
{
ctx.Response.StatusCode = 200;
await ctx.Response.StartAsync();
if (!ctx.Response.HasStarted)
throw new InvalidOperationException("response has started but HasStarted says it's not, in aws lambda!");
Console.WriteLine("this will only be printed with kestrel. won't print with aws lambda!");
});
app.Run(); i believe this is where the underlying value for this property is set by kestrel. so aws server should also do the same to keep in sync with the kestrel behavior i think. |
@heyjoey Is it fine to mark this issue as |
Thanks for reporting the issue @heyjoey and @dj-nitehawk. I agree this is a bug with how we are handling the response |
@heyjoey Good morning. Based on the testing, the issue doesn't appear to be reproducible in latest .NET 8 runtime. Below is sample code and output. <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<AWSProjectType>Lambda</AWSProjectType>
<!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<!-- Generate ready to run images during publishing to improvement cold starts. -->
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Amazon.Lambda.AspNetCoreServer.Hosting" Version="1.7.1" />
<PackageReference Include="FastEndpoints" Version="5.30.0" />
</ItemGroup>
</Project> Program.cs global using FastEndpoints;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Add AWS Lambda support. When application is run in Lambda Kestrel is swapped out as the web server with Amazon.Lambda.AspNetCoreServer. This
// package will act as the webserver translating request and responses between the Lambda event source and ASP.NET Core.
builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);
builder.Services.AddFastEndpoints();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseFastEndpoints();
app.MapControllers();
app.MapGet("/", () => "Welcome to running ASP.NET Core Minimal API on AWS Lambda");
app.MapGet("/test", () => new { testProp1 = "hellow", testProp2 = "world" });
app.Run();
public class MyRequest : Amazon.Lambda.APIGatewayEvents.APIGatewayHttpApiV2ProxyRequest
{
public string FirstName { get; set; } = "John";
public string LastName { get; set; } = "Doe";
public int Age { get; set; } = 0;
}
public class MyResponse
{
public string FullName { get; set; }
public bool IsOver18 { get; set; }
}
public class MyEndpoint : Endpoint<MyRequest>
{
public override void Configure()
{
Verbs(Http.POST);
Routes("/api/author");
AllowAnonymous();
}
public override async Task HandleAsync(MyRequest req, CancellationToken ct)
{
Logger.LogInformation($"Request Received: \n{req}");
var response = new MyResponse()
{
FullName = req.FirstName + " " + req.LastName,
IsOver18 = req.Age > 18
};
Logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(response));
// Added to see if AWS reports back event started
HttpContext.Response.OnStarting(() =>
{
Logger.LogInformation($"on starting event fires in aws");
return Task.CompletedTask;
});
await SendAsync(response);
Logger.LogInformation($"request started: {HttpContext.Response.HasStarted}");
}
} Tested using PowerShell (on Windows) Invoke-WebRequest -Method POST -Uri 'https://<<REDACTED>>.execute-api.us-east-2.amazonaws.com/Prod/api/author' -Headers @{ "Content-Type" = "application/json"} -Body '{ "firstName": "John", "lastName": "Doe", "age": 16 }' Response StatusCode : 200
StatusDescription : OK
Content : {"fullName":"John Doe","isOver18":false}
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
X-Amzn-Trace-Id: Root=1-670ff9e2-16e670c6395ae63134e30328;Parent=2dda96de91fabe6c;Sampled=0;Lineage=1:37bd4e89:0
x-amzn-RequestId: 52956bec-128a-43b8-89e9-3fe...
Forms : {}
Headers : {[Connection, keep-alive], [X-Amzn-Trace-Id,
Root=1-670ff9e2-16e670c6395ae63134e30328;Parent=2dda96de91fabe6c;Sampled=0;Lineage=1:37bd4e89:0], [x-amzn-RequestId,
52956bec-128a-43b8-89e9-3fe1f6d6a399], [x-amz-apigw-id, fwP7dFVKCYcEdSA=]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 40 Tested using curl (on Unix/Mac)
Response
CloudWatch Logs
Please verify the same at your end. (I'm unsure on why Thanks, |
Thanks. Fix confirmed. |
Comments on closed issues are hard for our team to see. |
Description
When following the description to create a Minimal API with Amazon.Lambda.AspNetCoreServer.Hosting and added FastEndpoints, the response Dto is sent twice.
Reproduction Steps
Program.cs attached, created using serverless.AspNetCoreWebAPI project template and add a nuget package called FastEndpoints. Build and Publish to Lambda in Visual Studios 2022. Post payload as:
Response returned:
Logs
screenshot attached.
Environment
Resolution
It seems that Amazon.Lambda.AspNetCoreServer did not set the HasStarted property of the IHttpResponseFeature which the HttpContext reads from.
This is a 🐛 bug-report
Program.cs.txt
The text was updated successfully, but these errors were encountered: