Description
Describe the bug
I wish return HTML direct to client from HTTPS Direct URL with AWS Lambda AOT Application, but it not work, return with content-type application/octet alwayes.
How to solve this problem?
Problem List
- APIGatewayProxyResponse with follwing parameter, but respose is content-type application/octet-stream.
- Overwrite APIGatewayProxyResponse by generated JsonDeserizer, but respose is content-type application/octet-stream.
- Specify TrimmerRootAssembly that Amazon.Lambda.APIGatewayEvents", but respose is content-type application/octet-stream.
- Overwrite LambdaSerializer by custom Serializer, but respose is content-type application/octet-stream.
- Specify JsonSerializable for Dictionary<string, string> and APIGatewayProxyResponse, but respose is content-type application/octet-stream.
- Specify DynamicallyAccessedMembers DynamicallyAccessedMemberTypes.All, but respose is content-type application/octet-stream.
Source Code
Sorry, comment as Japanese
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
[assembly: LambdaSerializer(typeof(MyLambdaJsonSerializer))]
[JsonSerializable(typeof(Dictionary<string, string>))]
[JsonSerializable(typeof(APIGatewayProxyResponse))]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
internal partial class MyJsonContext : JsonSerializerContext { }
public class MyLambdaJsonSerializer : ILambdaSerializer
{
private readonly JsonSerializerOptions _options;
public MyLambdaJsonSerializer()
{
// ここで MyJsonContext.Default.Options を使用
_options = MyJsonContext.Default.Options;
}
public T Deserialize<T>(Stream stream)
{
return JsonSerializer.Deserialize<T>(stream, _options);
}
public void Serialize<T>(T response, Stream stream)
{
JsonSerializer.Serialize(stream, response, _options);
}
}
namespace CloudURLAOT01
{
public class Function
{
/// <summary>
/// 入力ストリームからデータを読み取り、FunctionHandlerを呼び出し、
/// 結果を出力ストリームに書き込むアダプター関数
/// </summary>
public static void StreamHandler(Stream input, ILambdaContext context, MemoryStream output)
{
// 入力ストリームからテキストを読み込む
string inputText;
using (var reader = new StreamReader(input))
{
inputText = reader.ReadToEnd();
}
// 最小限のAPIGatewayProxyRequestを作成(必要に応じてプロパティを追加してください)
var request = new APIGatewayProxyRequest { Body = inputText };
// FunctionHandlerを同期的に呼び出す
var function = new Function();
APIGatewayProxyResponse response = function.FunctionHandler(request, context);
// 出力ストリームに結果を書き込む(例:response.Bodyのみ)
using (var writer = new StreamWriter(output, leaveOpen: true))
{
writer.Write(response.Body);
writer.Flush();
}
output.Position = 0;
}
public static async Task Main(string[] args)
{
// ハンドラーを定義(ここではストリームベースの関数を利用)
var handler = (Action<Stream, ILambdaContext, MemoryStream>)StreamHandler;
// ビルダーから実行可能なブートストラップインスタンスを作成する
using var bootstrap = LambdaBootstrapBuilder.Create(handler).Build();
// ブートストラップインスタンスの RunAsync を呼び出してLambdaループを開始
await bootstrap.RunAsync();
}
public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
// クエリパラメータを手動で解析(Dictionary を使わず文字列処理)
string queryString = request.QueryStringParameters != null && request.QueryStringParameters.Count > 0
? string.Join("&", request.QueryStringParameters.Select(kv => $"{kv.Key}={kv.Value}"))
: "No query string";
// HTMLレスポンスの作成
string body = "<html><head><title>Lambda AOT</title></head><body>";
body += "<h1>Hello from AWS Lambda (Native AOT)!</h1>";
body += $"<p>QueryString: {queryString}</p>";
body += $"<p>Timestamp: {DateTime.UtcNow:O}</p>";
body += "</body></html>";
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Body = body,
IsBase64Encoded = false,
Headers = new Dictionary<string, string>
{
{ "Content-Type", "text/html; charset=utf-8" },
{ "Content-Disposition", "inline" }, // ブラウザに inline 表示を指示
{ "Access-Control-Allow-Methods", "GET, POST, OPTIONS" }
}
};
}
}
}
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
Recive HTML text with content-type text/html.
Current Behavior
All response is content-type application/octet-stream, but I wish text/html.
Reproduction Steps
Please try my sample program.
This program(you must remove additional logic for AOT) work well under non AOT, but under AOT, all of respose is content-type application/octet-stream.
Possible Solution
No response
Additional Information/Context
No response
AWS .NET SDK and/or Package version used
Amazon.Lambda.APIGatewayEvents 2.7.1
Amazon.Lambda.Core 2.5.1
Amazon.Lambda.RuntimeSupport 1.13.0
Amazon.Lambda.Serialization.SystemTextJson 2.4.4
Lambdajection.Core 0.9.2
Microsoft.DotNet.ILCompiler 8.0.16
Lambdajection.Framework 0.9.2
Targeted .NET Platform
.NET 8
Operating System and version
AWS Lambda HTTPS Direct