/// <summary> /// Convert the response coming from ASP.NET Core into APIGatewayProxyResponse which is /// serialized into the JSON object that API Gateway expects. /// </summary> /// <param name="responseFeatures"></param> /// <param name="statusCodeIfNotSet">Sometimes the ASP.NET server doesn't set the status code correctly when successful, so this parameter will be used when the value is 0.</param> /// <param name="lambdaContext"></param> /// <returns><see cref="APIGatewayProxyResponse"/></returns> protected override APIGatewayHttpApiV2ProxyResponse MarshallResponse(IHttpResponseFeature responseFeatures, ILambdaContext lambdaContext, int statusCodeIfNotSet = 200) { var response = new APIGatewayHttpApiV2ProxyResponse { StatusCode = responseFeatures.StatusCode != 0 ? responseFeatures.StatusCode : statusCodeIfNotSet }; string contentType = null; string contentEncoding = null; if (responseFeatures.Headers != null) { response.Headers = new Dictionary <string, string>(); foreach (var kvp in responseFeatures.Headers) { if (kvp.Key.Equals(HeaderNames.SetCookie, StringComparison.CurrentCultureIgnoreCase)) { // Cookies must be passed through the proxy response property and not as a // header to be able to pass back multiple cookies in a single request. response.Cookies = kvp.Value.ToArray(); continue; } response.SetHeaderValues(kvp.Key, kvp.Value.ToArray(), false); // Remember the Content-Type for possible later use if (kvp.Key.Equals("Content-Type", StringComparison.CurrentCultureIgnoreCase) && response.Headers[kvp.Key]?.Length > 0) { contentType = response.Headers[kvp.Key]; } else if (kvp.Key.Equals("Content-Encoding", StringComparison.CurrentCultureIgnoreCase) && response.Headers[kvp.Key]?.Length > 0) { contentEncoding = response.Headers[kvp.Key]; } } } if (contentType == null) { response.Headers["Content-Type"] = null; } if (responseFeatures.Body != null) { // Figure out how we should treat the response content, check encoding first to see if body is compressed, then check content type var rcEncoding = GetResponseContentEncodingForContentEncoding(contentEncoding); if (rcEncoding != ResponseContentEncoding.Base64) { rcEncoding = GetResponseContentEncodingForContentType(contentType); } (response.Body, response.IsBase64Encoded) = Utilities.ConvertAspNetCoreBodyToLambdaBody(responseFeatures.Body, rcEncoding); } PostMarshallResponseFeature(responseFeatures, response, lambdaContext); _logger.LogDebug($"Response Base 64 Encoded: {response.IsBase64Encoded}"); return(response); }
public async Task Invoke(HttpContext context) { string endpoint = GetLoweredTrimedPath(context.Request.Path); var status = (EndpointStatus)EndpointStatus[endpoint]; if (status == null) { status = (EndpointStatus)EndpointStatus["*"]; } if (status != null && CheckLimitExceeded(status)) { if (!context.RequestAborted.IsCancellationRequested) { IHttpResponseFeature responseFeature = context.Features.Get <IHttpResponseFeature>(); responseFeature.StatusCode = StatusCodes.Status503ServiceUnavailable; responseFeature.ReasonPhrase = "Concurrent request limit exceeded."; } } else { try { await _next(context); } finally { if (ShouldDecrementConcurrentRequestsCountAsync(status.Limit)) { Interlocked.Decrement(ref status.ConcurrentRequestsCount); } } } }
/// <summary> /// Convert the response coming from ASP.NET Core into APIGatewayProxyResponse which is /// serialized into the JSON object that API Gateway expects. /// </summary> /// <returns>The response.</returns> /// <param name="responseFeatures">Response features.</param> /// <param name="fcContext">Fc context.</param> /// <param name="statusCodeIfNotSet">Status code if not set.</param> protected HttpResponse MarshallResponse(IHttpResponseFeature responseFeatures, IFcContext fcContext, HttpResponse response, int statusCodeIfNotSet = 200) { response.StatusCode = responseFeatures.StatusCode != 0 ? responseFeatures.StatusCode : statusCodeIfNotSet; string contentType = null; if (responseFeatures.Headers != null) { foreach (var kvp in responseFeatures.Headers) { response.Headers[kvp.Key] = kvp.Value; // Remember the Content-Type for possible later use if (kvp.Key.Equals("Content-Type", StringComparison.CurrentCultureIgnoreCase)) { contentType = response.Headers[kvp.Key]; } } } if (contentType == null) { response.Headers["Content-Type"] = StringValues.Empty; } response.Body = responseFeatures.Body; PostMarshallResponseFeature(responseFeatures, response, fcContext); return(response); }
/// <summary> /// Convert the response coming from ASP.NET Core into APIGatewayProxyResponse which is /// serialized into the JSON object that API Gateway expects. /// </summary> /// <param name="responseFeatures"></param> /// <returns></returns> private APIGatewayProxyResponse MarshallResponse(IHttpResponseFeature responseFeatures) { var response = new APIGatewayProxyResponse { StatusCode = responseFeatures.StatusCode }; if (responseFeatures.Headers != null) { response.Headers = new Dictionary <string, string>(); foreach (var kvp in responseFeatures.Headers) { if (kvp.Value.Count == 1) { response.Headers[kvp.Key] = kvp.Value[0]; } else { response.Headers[kvp.Key] = string.Join(",", kvp.Value); } } } if (responseFeatures.Body != null) { responseFeatures.Body.Position = 0; using (StreamReader reader = new StreamReader(responseFeatures.Body, Encoding.UTF8)) { response.Body = reader.ReadToEnd(); } } return(response); }
// This IHttpResponseFeature extension method extracts custom metric datapoints from the headers of a IHttpResponseFeature object. internal static List <DataPoint> ExtractCustomMetricDataPoints(this IHttpResponseFeature responseFeature) { var metricDataPointHeaders = new List <KeyValuePair <string, StringValues> >(); foreach (var kvp in responseFeature.Headers) { if (kvp.Key.StartsWith(CustomMetricPrefix, StringComparison.Ordinal)) { metricDataPointHeaders.Add(kvp); } } if (metricDataPointHeaders.Count == 0) { return(null); } var dataPoints = new List <DataPoint>(metricDataPointHeaders.Count); foreach (var metricDataPointHeader in metricDataPointHeaders) { dataPoints.Add(JsonConvert.DeserializeObject <DataPoint>(metricDataPointHeader.Value)); responseFeature.Headers.Remove(metricDataPointHeader.Key); } return(dataPoints); }
public async Task WriteAsync(Stream stream, object feature, CancellationToken token) { IHttpResponseFeature hrf = (IHttpResponseFeature)feature; if (hrf.Body != Stream.Null && !hrf.Headers.ContentLength.HasValue) { hrf.Headers.ContentLength = hrf.Body.Length; } var buffer = new BufferedStream(stream); using (var writer = new BinaryWriter(buffer, Encoding.UTF8, true)) { writer.Write(hrf.StatusCode); writer.Write(hrf.ReasonPhrase ?? String.Empty); WriteHeaders(writer, hrf.Headers); } await stream.FlushAsync(token); if (hrf.Body != Stream.Null && hrf.Body.Length > 0) { hrf.Body.Seek(0, SeekOrigin.Begin); await hrf.Body.CopyToAsync(stream, 81920, token); await stream.FlushAsync(token); } }
public AspNetHttpResponse(HttpContext context, Microsoft.AspNetCore.Http.HttpResponse response) { this.Context = context; this.response = response; this.responseFeature = response.HttpContext.Features.Get <IHttpResponseFeature>(); this.Headers = new AspNetHeaderDictionary(response.Headers); }
public async Task Invoke(HttpContext context) { if (context.Request.Path != "/pdf/process") { await _next(context); return; } if (CheckLimitExceeded() && !(await TryWaitInQueueAsync(context.RequestAborted))) { if (!context.RequestAborted.IsCancellationRequested) { IHttpResponseFeature responseFeature = context.Features.Get <IHttpResponseFeature>(); responseFeature.StatusCode = StatusCodes.Status503ServiceUnavailable; responseFeature.ReasonPhrase = "Concurrent request limit exceeded."; } } else { try { await _next(context); } finally { if (await ShouldDecrementConcurrentRequestsCountAsync()) { Interlocked.Decrement(ref _concurrentRequestsCount); } } } }
private Task SendResponseAsync( IMqResponseFeature mqResponse, IHttpResponseFeature httpResponse, IHeaderConverter headerConverter ) { var needPublish = false; var needAck = mqResponse.AckDeliveryTag.HasValue; if (mqResponse.Exchange != null) { MergeResponseHeaders(mqResponse, httpResponse, headerConverter); needPublish = true; } return(Task.Run(() => { if (needPublish) { _mqConnection.Model.BasicPublish(mqResponse.Exchange, mqResponse.RoutingKey, mqResponse.Mandatory, mqResponse.Properties, GetBody(mqResponse)); } if (needAck) { _mqConnection.Model.BasicAck(mqResponse.AckDeliveryTag.Value, multiple: false); } })); }
private void SetError(IHttpResponseFeature responseFeature, Int32 statusCode, Exception exception) { if (responseFeature == null || responseFeature.HasStarted) { return; } responseFeature.StatusCode = statusCode; }
void IFeatureCache.CheckFeaturesRevision() { if (_cachedFeaturesRevision != _features.Revision) { _response = null; _cachedFeaturesRevision = _features.Revision; } }
public StubHttpResponse(StubHttpContext context) { HttpContext = context; _feature = context.Features.Get <IHttpResponseFeature>(); Cookies = new ResponseCookies(Headers, new DefaultObjectPool <StringBuilder>(new DefaultPooledObjectPolicy <StringBuilder>())); }
void IFeatureCache.CheckFeaturesRevision() { if (_cachedFeaturesRevision != _features.Revision) { _response = null; _cachedFeaturesRevision = _features.Revision; } }
/// <summary> /// Convert the response coming from ASP.NET Core into APIGatewayProxyResponse which is /// serialized into the JSON object that API Gateway expects. /// </summary> /// <param name="responseFeatures"></param> /// <param name="statusCodeIfNotSet">Sometimes the ASP.NET server doesn't set the status code correctly when successful, so this parameter will be used when the value is 0.</param> /// <param name="lambdaContext"></param> /// <returns><see cref="APIGatewayProxyResponse"/></returns> protected override APIGatewayProxyResponse MarshallResponse(IHttpResponseFeature responseFeatures, ILambdaContext lambdaContext, int statusCodeIfNotSet = 200) { var response = new APIGatewayProxyResponse { StatusCode = responseFeatures.StatusCode != 0 ? responseFeatures.StatusCode : statusCodeIfNotSet }; string contentType = null; string contentEncoding = null; if (responseFeatures.Headers != null) { response.MultiValueHeaders = new Dictionary <string, IList <string> >(); response.Headers = new Dictionary <string, string>(); foreach (var kvp in responseFeatures.Headers) { response.MultiValueHeaders[kvp.Key] = kvp.Value.ToList(); // Remember the Content-Type for possible later use if (kvp.Key.Equals("Content-Type", StringComparison.CurrentCultureIgnoreCase) && response.MultiValueHeaders[kvp.Key].Count > 0) { contentType = response.MultiValueHeaders[kvp.Key][0]; } else if (kvp.Key.Equals("Content-Encoding", StringComparison.CurrentCultureIgnoreCase) && response.MultiValueHeaders[kvp.Key].Count > 0) { contentEncoding = response.MultiValueHeaders[kvp.Key][0]; } } } if (contentType == null) { response.MultiValueHeaders["Content-Type"] = new List <string>() { null }; } if (responseFeatures.Body != null) { // Figure out how we should treat the response content, check encoding first to see if body is compressed, then check content type var rcEncoding = GetResponseContentEncodingForContentEncoding(contentEncoding); if (rcEncoding != ResponseContentEncoding.Base64) { rcEncoding = GetResponseContentEncodingForContentType(contentType); } (response.Body, response.IsBase64Encoded) = Utilities.ConvertAspNetCoreBodyToLambdaBody(responseFeatures.Body, rcEncoding); } PostMarshallResponseFeature(responseFeatures, response, lambdaContext); _logger.LogDebug($"Response Base 64 Encoded: {response.IsBase64Encoded}"); return(response); }
private static void MergeResponseHeaders(IMqResponseFeature mqResponse, IHttpResponseFeature httpResponse, IHeaderConverter headerConverter) { var headers = mqResponse.Properties.Headers; foreach (var item in httpResponse.Headers) { headers[item.Key] = headerConverter.Write(item.Value); } }
internal WebContext(IFeatureCollection features) { this.features = features; connection = new DefaultConnectionInfo(features); fRequest = features.Get <IHttpRequestFeature>(); fRequestCookies = new RequestCookiesFeature(features); fResponse = features.Get <IHttpResponseFeature>(); fWebSocket = features.Get <IHttpWebSocketFeature>(); }
/// <inheritdoc/> protected override ApplicationLoadBalancerResponse MarshallResponse(IHttpResponseFeature responseFeatures, ILambdaContext lambdaContext, int statusCodeIfNotSet = 200) { var response = new ApplicationLoadBalancerResponse { StatusCode = responseFeatures.StatusCode != 0 ? responseFeatures.StatusCode : statusCodeIfNotSet }; response.StatusDescription = $"{response.StatusCode} {((System.Net.HttpStatusCode)response.StatusCode).ToString()}"; string contentType = null; if (responseFeatures.Headers != null) { if (this._multiHeaderValuesEnabled) { response.MultiValueHeaders = new Dictionary <string, IList <string> >(); } else { response.Headers = new Dictionary <string, string>(); } foreach (var kvp in responseFeatures.Headers) { if (this._multiHeaderValuesEnabled) { response.MultiValueHeaders[kvp.Key] = kvp.Value.ToList(); } else { response.Headers[kvp.Key] = kvp.Value[0]; } // Remember the Content-Type for possible later use if (kvp.Key.Equals("Content-Type", StringComparison.CurrentCultureIgnoreCase)) { contentType = kvp.Value[0]; } } } if (responseFeatures.Body != null) { // Figure out how we should treat the response content var rcEncoding = GetResponseContentEncodingForContentType(contentType); (response.Body, response.IsBase64Encoded) = Utilities.ConvertAspNetCoreBodyToLambdaBody(responseFeatures.Body, rcEncoding); } PostMarshallResponseFeature(responseFeatures, response, lambdaContext); _logger.LogDebug($"Response Base 64 Encoded: {response.IsBase64Encoded}"); return(response); }
public HalHttpResponse(HttpContext context) { this.HttpContext = context ?? throw new ArgumentNullException(nameof(context)); this.responseFeature = context.Features.Get <IHttpResponseFeature>() ?? throw new ArgumentException( "context should contain a IHttpResponseFeature", nameof(context)); }
// This IHttpResponseFeature extension method gets custom metric datapoints from the headers of a IHttpResponseFeature object. internal static List <DataPoint> GetCustomMetricDataPoints(this IHttpResponseFeature responseFeature) { var dataPoints = from metricDataPointHeader in (from header in responseFeature.Headers where header.Key.StartsWith(CustomMetricPrefix, StringComparison.Ordinal) select header) select JsonConvert.DeserializeObject <DataPoint>(metricDataPointHeader.Value); return(dataPoints.ToList()); }
private HttpContext GetHttpContext(IHttpResponseFeature responseFeature = null) { if (responseFeature == null) { responseFeature = new TestResponseFeature(); } var httpContext = new DefaultHttpContext(); httpContext.Features.Set <IHttpResponseFeature>(responseFeature); return(httpContext); }
/// <inheritdoc /> /// <summary> /// This overriding method is called after the APIGatewayProxyFunction has marshaled IHttpResponseFeature that came /// back from making the request into ASP.NET Core into API Gateway's response object APIGatewayProxyResponse. It gets the /// user-defined custom metric datapoints from the response headers, posts them to SignalFx and removes the headers. /// </summary> protected override void PostMarshallResponseFeature(IHttpResponseFeature aspNetCoreResponseFeature, APIGatewayProxyResponse apiGatewayResponse, ILambdaContext lambdaContext) { var dataPoints = aspNetCoreResponseFeature.GetCustomMetricDataPoints(); foreach (var dataPoint in dataPoints) { dataPoint.AddDefaultDimensions(lambdaContext); } PostDataPoints(dataPoints); aspNetCoreResponseFeature.RemoveCustomMetricDataPointHeaders(); }
// This IHttpResponseFeature extension method removes custom metric datapoints headers from a IHttpResponseFeature object. internal static void RemoveCustomMetricDataPointHeaders(this IHttpResponseFeature responseFeature) { var metricDataPointHeaders = from header in responseFeature.Headers where header.Key.StartsWith(CustomMetricPrefix, StringComparison.Ordinal) select header; foreach (var metricDataPointHeader in metricDataPointHeaders.ToList()) { responseFeature.Headers.Remove(metricDataPointHeader.Key); } }
private async Task AssertExecution(IHttpRequestFeature requestFeature, IHttpResponseFeature responseFeature, BatchMiddlewareEvents batchMiddlewareEvents, params ResponseFeature[] responseFeatures) { var featureCollection = new FeatureCollection(); featureCollection.Set(requestFeature); featureCollection.Set(responseFeature); var defaultContext = new DefaultHttpContext(featureCollection); var middleware = CreateMiddleware(CreateRequestDelegate(responseFeatures), batchMiddlewareEvents); await middleware.Invoke(defaultContext).ConfigureAwait(false); }
public async Task Invoke(HttpContext context) { try { await requestDelegate.Invoke(context); } catch (HttpException httpException) { context.Response.StatusCode = (int)httpException.StatusCode; IHttpResponseFeature feature = context.Features.Get <IHttpResponseFeature>(); feature.ReasonPhrase = httpException.Message; } }
protected override void PostMarshallResponseFeature( IHttpResponseFeature aspNetCoreResponseFeature, APIGatewayProxyResponse lambdaResponse, ILambdaContext lambdaContext) { base.PostMarshallResponseFeature(aspNetCoreResponseFeature, lambdaResponse, lambdaContext); AppLogger.LogJson(new { Event = "Response", RequestId = lambdaContext.AwsRequestId, StatusCode = lambdaResponse.StatusCode, }); }
public StubHttpResponse(StubHttpContext context) { HttpContext = context; _httpResponseFeature = context.Features.Get <IHttpResponseFeature>(); #if NETCOREAPP3_0 Cookies = new StubResponseCookieCollection(); _features = context.Features; _features.Set <IHttpResponseBodyFeature>(new StreamResponseBodyFeature(new MemoryStream())); #else Cookies = new ResponseCookies(Headers, new DefaultObjectPool <StringBuilder>(new DefaultPooledObjectPolicy <StringBuilder>())); #endif }
private static async Task CopyHttpResponseFeature(IHttpResponseFeature fromHttpResponseFeature, IHttpResponseFeature toHttpResponseFeature, CancellationToken token) { toHttpResponseFeature.StatusCode = fromHttpResponseFeature.StatusCode; toHttpResponseFeature.ReasonPhrase = fromHttpResponseFeature.ReasonPhrase; toHttpResponseFeature.Headers.Clear(); foreach (var pair in fromHttpResponseFeature.Headers) { toHttpResponseFeature.Headers[pair.Key] = pair.Value; } if (toHttpResponseFeature.Headers.ContentLength.GetValueOrDefault(1) > 0) { await fromHttpResponseFeature.Body.CopyToAsync(toHttpResponseFeature.Body, 81920, token); } }
public async Task Invoke(HttpContext context) { try { await this.next.Invoke(context); } catch (HttpException httpException) { context.Response.StatusCode = httpException.StatusCode; IHttpResponseFeature httpResponseFeature = context.Features.Get <IHttpResponseFeature>(); httpResponseFeature.ReasonPhrase = httpException.Message; } }
public async Task HandleAsync(HttpContext httpContext, Func <Task> _) { if (httpContext is null) { throw new ArgumentNullException(nameof(httpContext)); } LogRequestMessage(httpContext, Resources.Debug_HandlingRequest); CancellationToken cancellationToken = httpContext.RequestAborted; HttpResponse response = httpContext.Response; using HttpRequestMessage httpRequestMessage = new WrappedHttpRequest(httpContext.Request); cancellationToken.ThrowIfCancellationRequested(); HttpResponseMessage httpResponseMessage; IHttpResponseFeature responseFeature = httpContext.Features.Get <IHttpResponseFeature>(); try { httpResponseMessage = await SendAsync(httpRequestMessage, cancellationToken).ConfigureAwait(false); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { LogRequestMessage(httpContext, Resources.Error_VerifyMockSetup); #pragma warning disable CA2000 // Dispose objects before losing scope httpResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError) { ReasonPhrase = Resources.Error_VerifyMockSetup, Content = new StringContent(Resources.Error_VerifyMockSetup + Environment.NewLine + ex, Encoding.UTF8, "text/plain") }; #pragma warning restore CA2000 // Dispose objects before losing scope } finally { LogRequestMessage(httpContext, Resources.Debug_RequestHandled); } // Dispose message when response is done. response.RegisterForDispose(httpResponseMessage); cancellationToken.ThrowIfCancellationRequested(); await httpResponseMessage.MapToFeatureAsync(responseFeature, cancellationToken).ConfigureAwait(false); }
public override Task ExecuteResultAsync([NotNull] ActionContext context) { HttpResponse response = context.HttpContext.Response; try { response.StatusCode = (int)Response.StatusCode; IHttpResponseFeature responseFeature = context.HttpContext.Features.Get <IHttpResponseFeature>(); if (responseFeature != null) { responseFeature.ReasonPhrase = Response.ReasonPhrase; } HttpResponseHeaders headers = Response.Headers; // Ignore the Transfer-Encoding header if it is just "chunked". // We let the host decide about whether the response should be chunked or not. if (headers.TransferEncodingChunked == true && headers.TransferEncoding.Count == 1) { headers.TransferEncoding.Clear(); } foreach ((string key, IEnumerable <string> value) in headers) { response.Headers.Append(key, value.ToArray()); } HttpContentHeaders contentHeaders = Response.Content.Headers; // Copy the response content headers only after ensuring they are complete. // We ask for Content-Length first because HttpContent lazily computes this // and only afterwards writes the value into the content headers. long?_ = contentHeaders.ContentLength; foreach ((string key, IEnumerable <string> value) in contentHeaders) { response.Headers.Append(key, value.ToArray()); } return(Response.Content.CopyToAsync(response.Body)); } finally { ObjectHelper.Dispose(ref _response); } }
private string BuildOutputFileName(string fileName, IHttpResponseFeature httpResponseFeature) { var outFileName = Path.Combine(options.Value.OutboxPath, fileName); var info = new FileInfo(outFileName); var ext = info.Extension; if (httpResponseFeature.Headers["Content-Type"].Any(c => c.Contains("json"))) { ext = ".json"; } else if (httpResponseFeature.Headers["Content-Type"].Any(c => c.Contains("png"))) { ext = ".png"; } return(Path.Combine(info.Directory.FullName, DateTime.Now.Ticks.ToString() + "_" + info.Name.Replace(info.Extension, ext))); }