Exemple #1
0
        public virtual async Task InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
        {
            if (awm.IsSwagger(context) || !awm.IsApi(context))
            {
                await this._next(context);
            }
            else
            {
                var stopWatch = Stopwatch.StartNew();

                var request = await awm.FormatRequest(context.Request);

                var originalBodyStream = context.Response.Body;

                using (var newBodyStream = new MemoryStream())
                {
                    try
                    {
                        context.Response.Body = newBodyStream;
                        await _next.Invoke(context);

                        context.Response.Body = originalBodyStream;

                        var bodyAsText = await awm.FormatResponse(newBodyStream);

                        var actionIgnore = context.Response.Headers["AutoWrapIgnoreFilter"];
                        if (actionIgnore.Count > 0)
                        {
                            await awm.WrapIgnoreAsync(context, bodyAsText); return;
                        }

                        if (context.Response.StatusCode != Status304NotModified)
                        {
                            if (!_options.IsApiOnly && (bodyAsText.IsHtml() && !_options.BypassHTMLValidation) && context.Response.StatusCode == Status200OK)
                            {
                                context.Response.StatusCode = Status404NotFound;
                            }

                            if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) &&
                                bodyAsText.IsHtml() && context.Response.StatusCode == Status200OK)
                            {
                                if (newBodyStream.Length > 0)
                                {
                                    await awm.HandleSpaSupportAsync(context); return;
                                }
                            }
                            else if (context.Response.StatusCode == Status200OK)
                            {
                                await awm.HandleSuccessRequestAsync(context, bodyAsText, context.Response.StatusCode);
                            }
                            else
                            {
                                await awm.HandleNotSuccessRequestAsync(context, bodyAsText, context.Response.StatusCode);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        await awm.HandleExceptionAsync(context, ex);

                        newBodyStream.Seek(0, SeekOrigin.Begin);
                        await newBodyStream.CopyToAsync(originalBodyStream);
                    }
                    finally
                    {
                        LogResponse(context, request, stopWatch);
                    }
                }
            }
        }
Exemple #2
0
        public virtual async Task InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
        {
            if (awm.IsSwagger(context) || !awm.IsApi(context))
            {
                await _next(context);
            }
            else
            {
                var stopWatch   = Stopwatch.StartNew();
                var requestBody = await awm.GetRequestBodyAsync(context.Request);

                var  originalResponseBodyStream = context.Response.Body;
                bool isRequestOk = false;

                using var memoryStream = new MemoryStream();

                try
                {
                    context.Response.Body = memoryStream;
                    await _next.Invoke(context);

                    if (context.Response.HasStarted)
                    {
                        LogResponseHasStartedError(); return;
                    }

                    var actionIgnore = context.Request.Headers[TypeIdentifier.AutoWrapIgnoreFilterHeader];
                    if (actionIgnore.Count > 0)
                    {
                        await awm.RevertResponseBodyStreamAsync(memoryStream, originalResponseBodyStream);

                        return;
                    }

                    var bodyAsText = await awm.ReadResponseBodyStreamAsync(memoryStream);

                    context.Response.Body = originalResponseBodyStream;

                    if (context.Response.StatusCode != Status304NotModified && context.Response.StatusCode != Status204NoContent)
                    {
                        if (!_options.IsApiOnly &&
                            (bodyAsText.IsHtml() &&
                             !_options.BypassHTMLValidation) &&
                            context.Response.StatusCode == Status200OK)
                        {
                            context.Response.StatusCode = Status404NotFound;
                        }

                        if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) &&
                            (bodyAsText.IsHtml() &&
                             !_options.BypassHTMLValidation) &&
                            context.Response.StatusCode == Status200OK)
                        {
                            if (memoryStream.Length > 0)
                            {
                                await awm.HandleNotApiRequestAsync(context);
                            }
                            return;
                        }

                        isRequestOk = awm.IsRequestSuccessful(context.Response.StatusCode);
                        if (isRequestOk)
                        {
                            if (_options.IgnoreWrapForOkRequests)
                            {
                                await awm.WrapIgnoreAsync(context, bodyAsText);
                            }
                            else
                            {
                                await awm.HandleSuccessfulRequestAsync(context, bodyAsText, context.Response.StatusCode);
                            }
                        }
                        else
                        {
                            if (_options.UseApiProblemDetailsException)
                            {
                                await awm.HandleProblemDetailsExceptionAsync(context, _executor, bodyAsText);

                                return;
                            }

                            await awm.HandleUnsuccessfulRequestAsync(context, bodyAsText, context.Response.StatusCode);
                        }
                    }
                }
                catch (Exception exception)
                {
                    if (context.Response.HasStarted)
                    {
                        LogResponseHasStartedError(); return;
                    }

                    if (_options.UseApiProblemDetailsException)
                    {
                        await awm.HandleProblemDetailsExceptionAsync(context, _executor, null, exception);
                    }
                    else
                    {
                        await awm.HandleExceptionAsync(context, exception);
                    }

                    await awm.RevertResponseBodyStreamAsync(memoryStream, originalResponseBodyStream);
                }
                finally
                {
                    LogHttpRequest(context, requestBody, stopWatch, isRequestOk);
                }
            }
        }
Exemple #3
0
        public virtual async Task InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
        {
            if (awm.IsSwagger(context) || !awm.IsApi(context))
            {
                await this._next(context);
            }
            else
            {
                var stopWatch = Stopwatch.StartNew();

                var request = await awm.FormatRequest(context.Request);

                var originalBodyStream = context.Response.Body;

                using (var newBodyStream = new MemoryStream())
                {
                    try
                    {
                        context.Response.Body = newBodyStream;
                        await _next.Invoke(context);

                        context.Response.Body = originalBodyStream;

                        var bodyAsText = await awm.FormatResponse(newBodyStream);

                        var actionIgnore = context.Response.Headers["AutoWrapIgnoreFilter"];
                        if (actionIgnore.Count > 0)
                        {
                            await awm.WrapIgnoreAsync(context, bodyAsText); return;
                        }

                        if (context.Response.StatusCode != Status304NotModified)
                        {
                            if (!_options.IsApiOnly && bodyAsText.IsHtml() && context.Response.StatusCode == Status200OK)
                            {
                                context.Response.StatusCode = Status404NotFound;
                            }

                            if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) &&
                                bodyAsText.IsHtml() && context.Response.StatusCode == Status200OK)
                            {
                                if (newBodyStream.Length > 0)
                                {
                                    await awm.HandleSpaSupportAsync(context); return;
                                }
                            }
                            else if (context.Response.StatusCode == Status200OK)
                            {
                                await awm.HandleSuccessRequestAsync(context, bodyAsText, context.Response.StatusCode);
                            }
                            else
                            {
                                await awm.HandleNotSuccessRequestAsync(context, bodyAsText, context.Response.StatusCode);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        await awm.HandleExceptionAsync(context, ex);

                        newBodyStream.Seek(0, SeekOrigin.Begin);
                        await newBodyStream.CopyToAsync(originalBodyStream);
                    }
                    finally
                    {
                        stopWatch.Stop();

                        if (_options.EnableResponseLogging)
                        {
                            _logger.Log(LogLevel.Information, $@"Source:[{context.Connection.RemoteIpAddress.ToString() }] Request: {request} Responded with [{context.Response.StatusCode}] in {stopWatch.ElapsedMilliseconds}ms");
                        }
                    }
                }
            }
        }
Exemple #4
0
        public virtual async Task InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
        {
            if (awm.IsSwagger(context, _options.SwaggerPath) || !awm.IsApi(context) || awm.IsExclude(context, _options.ExcludePaths))
            {
                await _next(context);
            }
            else
            {
                (int statusCode, string response)finalResponse = (context.Response.StatusCode, string.Empty);
                var collector   = _diagnosticContext.BeginCollection();
                var stopWatch   = Stopwatch.StartNew();
                var requestBody = await awm.GetRequestBodyAsync(context.Request);

                Exception ex = null;
                var       originalResponseBodyStream = context.Response.Body;
                bool      isRequestOk        = false;
                string    responseBodyAsText = null;
                using var memoryStream = new MemoryStream();

                try
                {
                    context.Response.Body = memoryStream;
                    await _next.Invoke(context);

                    isRequestOk = awm.IsRequestSuccessful(context.Response.StatusCode);
                    if (context.Response.HasStarted)
                    {
                        LogResponseHasStartedError(context, requestBody, responseBodyAsText, stopWatch, isRequestOk, ex);
                        return;
                    }

                    var endpoint = context.GetEndpoint();
                    if (endpoint?.Metadata?.GetMetadata <AutoWrapIgnoreAttribute>() is object)
                    {
                        await awm.RevertResponseBodyStreamAsync(memoryStream, originalResponseBodyStream);

                        return;
                    }

                    responseBodyAsText = await awm.ReadResponseBodyStreamAsync(memoryStream);

                    context.Response.Body = originalResponseBodyStream;

                    if (context.Response.StatusCode != Status304NotModified &&
                        context.Response.StatusCode != Status204NoContent)
                    {
                        if (!_options.IsApiOnly &&
                            (responseBodyAsText.IsHtml() &&
                             !_options.BypassHTMLValidation) &&
                            context.Response.StatusCode == Status200OK)
                        {
                            context.Response.StatusCode = Status404NotFound;
                        }

                        if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) &&
                            (responseBodyAsText.IsHtml() &&
                             !_options.BypassHTMLValidation) &&
                            context.Response.StatusCode == Status200OK)
                        {
                            if (memoryStream.Length > 0)
                            {
                                await awm.HandleNotApiRequestAsync(context);
                            }

                            return;
                        }

                        isRequestOk = awm.IsRequestSuccessful(context.Response.StatusCode);
                        if (isRequestOk)
                        {
                            if (_options.IgnoreWrapForOkRequests)
                            {
                                await awm.WrapIgnoreAsync(context, responseBodyAsText);
                            }
                            else
                            {
                                finalResponse = await awm.HandleSuccessfulRequestAsync(context, responseBodyAsText,
                                                                                       context.Response.StatusCode);
                            }
                        }
                        else
                        {
                            if (_options.UseApiProblemDetailsException)
                            {
                                finalResponse = await awm.HandleProblemDetailsExceptionAsync(context, _executor, responseBodyAsText);

                                return;
                            }

                            finalResponse = await awm.HandleUnsuccessfulRequestAsync(context, responseBodyAsText,
                                                                                     context.Response.StatusCode);
                        }
                    }
                }
                catch (Exception exception)
                {
                    ex = exception;
                    if (context.Response.HasStarted)
                    {
                        LogResponseHasStartedError(context, requestBody, responseBodyAsText, stopWatch, isRequestOk,
                                                   ex);
                        return;
                    }

                    if (_options.UseApiProblemDetailsException)
                    {
                        finalResponse = await awm.HandleProblemDetailsExceptionAsync(context, _executor, null, exception);
                    }
                    else
                    {
                        finalResponse = await awm.HandleExceptionAsync(context, exception);
                    }

                    responseBodyAsText = await awm.ReadResponseBodyStreamAsync(memoryStream);

                    await awm.RevertResponseBodyStreamAsync(memoryStream, originalResponseBodyStream);
                }
                finally
                {
                    if (string.IsNullOrWhiteSpace(finalResponse.response))
                    {
                        finalResponse.response = responseBodyAsText;
                    }
                    LogHttpRequest(context, collector, requestBody, finalResponse.response, finalResponse.statusCode, stopWatch, isRequestOk, ex);
                }
            }
        }
        public virtual async Task InvokeAsyncBase(HttpContext context, AutoWrapperMembers awm)
        {
            if (awm.IsSwagger(context) || !awm.IsApi(context))
            {
                await this._next(context);
            }
            else
            {
                var stopWatch = Stopwatch.StartNew();

                var request = await awm.FormatRequest(context.Request);

                var originalBodyStream = context.Response.Body;

                using (var newBodyStream = new MemoryStream())
                {
                    try
                    {
                        context.Response.Body = newBodyStream;
                        await _next.Invoke(context);

                        context.Response.Body = originalBodyStream;

                        var bodyAsText = await awm.FormatResponse(newBodyStream);

                        if (context.Response.StatusCode != 304)
                        {
                            if (!_options.IsApiOnly && bodyAsText.IsHtml() && context.Response.StatusCode == 200)
                            {
                                context.Response.StatusCode = 404;
                            }

                            if (!context.Request.Path.StartsWithSegments(new PathString(_options.WrapWhenApiPathStartsWith)) &&
                                bodyAsText.IsHtml() && context.Response.StatusCode == 200)
                            {
                                if (newBodyStream.Length > 0)
                                {
                                    await awm.HandleSpaSupportAsync(context); return;
                                }
                            }
                            else if (context.Response.StatusCode == 200)
                            {
                                await awm.HandleSuccessRequestAsync(context, bodyAsText, context.Response.StatusCode);
                            }
                            else
                            {
                                await awm.HandleNotSuccessRequestAsync(context, context.Response.StatusCode);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        await awm.HandleExceptionAsync(context, ex);

                        newBodyStream.Seek(0, SeekOrigin.Begin);
                        await newBodyStream.CopyToAsync(originalBodyStream);
                    }
                    finally
                    {
                        stopWatch.Stop();
                        _logger.Log(LogLevel.Information, $@"Request: {request} Responded with [{context.Response.StatusCode}] in {stopWatch.ElapsedMilliseconds}ms");
                    }
                }
            }
        }