// this will build a mock ApiRequest/Response and record the logs/metrics of the underlying mvc middleware public static RequestDelegate WithAlteredAspNet(RequestDelegate aspnet, CloudwatchLogsSink cloudwatchLogs, CloudwatchMetricsSink cloudwatchMetrics) { return(async(httpContext) => { var request = httpContext.Request; var mvcRequest = new AlteredApiRequest { Path = request.Path, HttpMethod = request.Method, Headers = request.Headers, QueryStringParameters = QueryHelpers.ParseQuery(request.QueryString.Value) }; var pipeline = new AlteredPipeline <AlteredApiRequest, AlteredApiResponse>(async(_) => { await aspnet(httpContext); var mvcResponse = new AlteredApiResponse { StatusCode = httpContext.Response.StatusCode, Headers = httpContext.Response?.Headers }; return mvcResponse; }) .WithCloudwatchLogs(cloudwatchLogs, mvcRequest.Path) .WithCloudwatchMetrics(cloudwatchMetrics, mvcRequest.Path); var response = await pipeline.Execute(mvcRequest); }); }
// todo https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html // https://docs.aws.amazon.com/general/latest/gr/sigv4_elements.html public static AlteredApiRequest WithAws(this AlteredApiRequest request) { var amzDate = DateTime.UtcNow.ToString("YYYYMMDD'T'HHMMSS'Z'"); request.Headers["x-amz-date"] = amzDate; return(request); }
// translate MvcRequest/Response into aspnet RequestDelegate public static RequestDelegate ToAlteredAspNet(this IAlteredPipeline <AlteredApiRequest, AlteredApiResponse> pipeline) => async(httpContext) => { var request = httpContext.Request; using (var bodyReader = new StreamReader(request.Body)) { var mvcRequest = new AlteredApiRequest { Path = request.Path, HttpMethod = request.Method, Headers = request.Headers, QueryStringParameters = QueryHelpers.ParseQuery(request.QueryString.Value) }; if (request.Body?.CanRead == true) { mvcRequest.Body = await bodyReader.ReadToEndAsync(); } var mvcResponse = await pipeline.Execute(mvcRequest); var response = httpContext.Response; response.StatusCode = mvcResponse.StatusCode; foreach (var kvp in mvcResponse.Headers) { response.Headers[kvp.Key] = kvp.Value; } if (!string.IsNullOrEmpty(mvcResponse.Body)) { //response.ContentLength = mvcResponse.Body.Length; response.ContentType = response.Headers[HeaderNames.ContentType]; using (var bodyWriter = new StreamWriter(response.Body)) { await bodyWriter.WriteAsync(mvcResponse.Body); } } } };
public Lambda(IAlteredPipeline <AlteredApiRequest, AlteredApiResponse> pipeline) : base(async(request) => { var body = request.IsBase64Encoded ? Convert.ToBase64String(Encoding.UTF8.GetBytes(request.Body)) : request.Body; var mvcRequest = new AlteredApiRequest { Path = request.Path, HttpMethod = request.HttpMethod, Headers = request.Headers.ToDictionary(kvp => kvp.Key, kvp => new StringValues(kvp.Value)), QueryStringParameters = request.QueryStringParameters.ToDictionary(kvp => kvp.Key, kvp => new StringValues(kvp.Value)), Body = body }; try { var mvcResponse = await pipeline.Execute(mvcRequest); var response = new ApplicationLoadBalancerResponse { StatusCode = mvcResponse.StatusCode, Headers = mvcResponse.Headers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString()), Body = mvcResponse.Body }; return(response); } catch (Exception e) { // lambda will write error + request if thrown to Console.Error.WriteLine(AlteredJson.SerializeObject(new { e.Message, e.Source, StackTrace = new StackTrace(e).ToString(), e.Data })); Console.Out.WriteLine(AlteredJson.SerializeObject(mvcRequest)); throw e; } }) { }