in Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Extensions/HttpContextExtensions.cs [23:120]
public static async Task<APIGatewayHttpApiV2ProxyRequest> ToApiGatewayHttpV2Request(
this HttpContext context,
ApiGatewayRouteConfig apiGatewayRouteConfig)
{
var request = context.Request;
var currentTime = DateTimeOffset.UtcNow;
var body = await HttpRequestUtility.ReadRequestBody(request);
var contentLength = HttpRequestUtility.CalculateContentLength(request, body);
var pathParameters = RouteTemplateUtility.ExtractPathParameters(apiGatewayRouteConfig.Path, request.Path);
// Format 2.0 doesn't have multiValueHeaders or multiValueQueryStringParameters fields. Duplicate headers are combined with commas and included in the headers field.
// 2.0 also lowercases all header keys
var (_, allHeaders) = HttpRequestUtility.ExtractHeaders(request.Headers, true);
var headers = allHeaders.ToDictionary(
kvp => kvp.Key,
kvp => string.Join(", ", kvp.Value)
);
// Duplicate query strings are combined with commas and included in the queryStringParameters field.
var (_, allQueryParams) = HttpRequestUtility.ExtractQueryStringParameters(request.Query);
var queryStringParameters = allQueryParams.ToDictionary(
kvp => kvp.Key,
kvp => string.Join(",", kvp.Value)
);
string userAgent = request.Headers.UserAgent.ToString();
if (!headers.ContainsKey("content-length"))
{
headers["content-length"] = contentLength.ToString();
}
if (!headers.ContainsKey("content-type"))
{
headers["content-type"] = "text/plain; charset=utf-8";
}
var httpApiV2ProxyRequest = new APIGatewayHttpApiV2ProxyRequest
{
RouteKey = $"{request.Method} {apiGatewayRouteConfig.Path}",
RawPath = request.Path.Value, // this should be decoded value
Body = body,
IsBase64Encoded = false,
RequestContext = new ProxyRequestContext
{
Http = new HttpDescription
{
Method = request.Method,
Path = request.Path.Value, // this should be decoded value
Protocol = !string.IsNullOrEmpty(request.Protocol) ? request.Protocol : "HTTP/1.1", // defaults to http 1.1 if not provided
UserAgent = userAgent
},
Time = currentTime.ToString("dd/MMM/yyyy:HH:mm:ss") + " +0000",
TimeEpoch = currentTime.ToUnixTimeMilliseconds(),
RequestId = HttpRequestUtility.GenerateRequestId(),
RouteKey = $"{request.Method} {apiGatewayRouteConfig.Path}",
},
Version = "2.0"
};
if (request.Cookies.Any())
{
httpApiV2ProxyRequest.Cookies = request.Cookies.Select(c => $"{c.Key}={c.Value}").ToArray();
}
if (headers.Any())
{
httpApiV2ProxyRequest.Headers = headers;
}
httpApiV2ProxyRequest.RawQueryString = string.Empty; // default is empty string
if (queryStringParameters.Any())
{
// this should be decoded value
httpApiV2ProxyRequest.QueryStringParameters = queryStringParameters;
// this should be the url encoded value and not include the "?"
// e.g. key=%2b%2b%2b
httpApiV2ProxyRequest.RawQueryString = HttpUtility.UrlPathEncode(request.QueryString.Value?.Substring(1));
}
if (pathParameters.Any())
{
// this should be decoded value
httpApiV2ProxyRequest.PathParameters = pathParameters;
}
if (HttpRequestUtility.IsBinaryContent(request.ContentType))
{
// we already converted it when we read the body so we dont need to re-convert it
httpApiV2ProxyRequest.IsBase64Encoded = true;
}
return httpApiV2ProxyRequest;
}