/// <summary>
    /// Executes the middleware.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
    /// <returns>A task that represents the execution of this middleware.</returns>
    public async Task Invoke(HttpContext context)
    {
        var statusCodeFeature = new StatusCodePagesFeature();

        context.Features.Set <IStatusCodePagesFeature>(statusCodeFeature);

        await _next(context);

        if (!statusCodeFeature.Enabled)
        {
            // Check if the feature is still available because other middleware (such as a web API written in MVC) could
            // have disabled the feature to prevent HTML status code responses from showing up to an API client.
            return;
        }

        // Do nothing if a response body has already been provided.
        if (context.Response.HasStarted ||
            context.Response.StatusCode < 400 ||
            context.Response.StatusCode >= 600 ||
            context.Response.ContentLength.HasValue ||
            !string.IsNullOrEmpty(context.Response.ContentType))
        {
            return;
        }

        var statusCodeContext = new StatusCodeContext(context, _options, _next);
        await _options.HandleAsync(statusCodeContext);
    }
예제 #2
0
        private async Task RenderStatusCodeAsync(StatusCodeContext ctx)
        {
            var json = JsonConvert.SerializeObject(new SimpleErrorModel(Activity.Current?.Id ?? ctx.HttpContext.TraceIdentifier), Formatting.Indented);

            ctx.HttpContext.Response.ContentType = "application/json";
            await ctx.HttpContext.Response.WriteAsync(json, Utilities.UTF8).ConfigureAwait(false);
        }
예제 #3
0
파일: Errors.cs 프로젝트: wpbrown/oakproxy
        public static async Task StatusPageAsync(StatusCodeContext context)
        {
            var  accept = context.HttpContext.Request.GetTypedHeaders().Accept;
            bool json   = accept is null || accept.Count == 0 || accept.Any(x => ApplicationJson.IsSubsetOf(x));

            string type, content;

            (Code code, string message) = context.HttpContext.GetErrorDetail();
            int status     = context.HttpContext.Response.StatusCode;
            int codeNumber = (int)code;

            if (json)
            {
                type    = "application/json";
                content = $"{{\"error\":{{\"source\":\"OAKProxy\",\"status\":{status},\"code\":{codeNumber},\"message\":\"{message}\"}}}}";
            }
            else
            {
                type    = "text/plain";
                content = $"OAKProxy Error Status[{status}] Code[{codeNumber}] Message[{message}]";
            }

            context.HttpContext.Response.ContentType = type;
            await context.HttpContext.Response.WriteAsync(content, context.HttpContext.RequestAborted);
        }
        private static Task Unauthorized(this StatusCodeContext context)
        {
            var response = new
            {
                Message  = "Unauthorized",
                HttpCode = context.HttpContext.Response.StatusCode
            };

            return(context.HttpContext.Response.WriteAsync(Output(response)));
        }
예제 #5
0
 protected virtual async Task OnApiCallAsync(StatusCodeContext context, int statusCode)
 {
     context.HttpContext.Response.ContentType = "application/json;charset=utf-8";
     context.HttpContext.Response.StatusCode  = 200;
     await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(new
     {
         Code    = statusCode,
         Message = ""
     }));
 }
        private static Task Forbidden(this StatusCodeContext context)
        {
            var response = new
            {
                Message  = "Forbidden",
                HttpCode = context.HttpContext.Response.StatusCode
            };

            return(context.HttpContext.Response.WriteAsync(Output(response)));
        }
        private static Task InternalServerError(this StatusCodeContext context)
        {
            var response = new
            {
                Message  = "InternalServerError",
                HttpCode = context.HttpContext.Response.StatusCode
            };

            return(context.HttpContext.Response.WriteAsync(Output(response)));
        }
예제 #8
0
        protected virtual async Task OnWebCallAsync(StatusCodeContext context, int statusCode)
        {
            var options    = EngineContext.Current.Resolve <IOptions <MozOptions> >()?.Value;
            var pathFormat = options?.ErrorPage?.DefaultRedirect;

            if (statusCode == 401 && !string.IsNullOrEmpty(options?.ErrorPage?.LoginRedirect))
            {
                pathFormat = options?.ErrorPage?.LoginRedirect;
            }
            if (statusCode == 404 && !string.IsNullOrEmpty(options?.ErrorPage?.NotFoundRedirect))
            {
                pathFormat = options?.ErrorPage?.NotFoundRedirect;
            }

            if (string.IsNullOrEmpty(pathFormat))
            {
                context.HttpContext.Response.ContentType = "text/html;charset=utf-8";
                context.HttpContext.Response.StatusCode  = 200;
                await context.HttpContext.Response.WriteAsync($"哦豁!系统不想理你,并扔了一个 {statusCode} 页面给你。");
            }
            else
            {
                var newPath = new PathString(string.Format(CultureInfo.InvariantCulture, pathFormat, context.HttpContext.Response.StatusCode));

                var originalPath        = context.HttpContext.Request.Path;
                var originalQueryString = context.HttpContext.Request.QueryString;
                // Store the original paths so the app can check it.
                context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
                {
                    OriginalPathBase    = context.HttpContext.Request.PathBase.Value,
                    OriginalPath        = originalPath.Value,
                    OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
                });

                // An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
                // the endpoint and route values to ensure things are re-calculated.
                context.HttpContext.SetEndpoint(endpoint: null);
                var routeValuesFeature = context.HttpContext.Features.Get <IRouteValuesFeature>();
                routeValuesFeature?.RouteValues?.Clear();

                context.HttpContext.Request.Path = newPath;
                //context.HttpContext.Request.QueryString = newQueryString;
                try
                {
                    await context.Next(context.HttpContext);
                }
                finally
                {
                    context.HttpContext.Request.QueryString = originalQueryString;
                    context.HttpContext.Request.Path        = originalPath;
                    context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(null);
                }
            }
        }
예제 #9
0
 public static async Task Handler(StatusCodeContext context)
 {
     if (context.HttpContext.Response.StatusCode > 500)
     {
         await context.HttpContext.Response.WriteAsync($"ServerError{context.HttpContext.Response.StatusCode}");
     }
     else
     {
         await context.HttpContext.Response.WriteAsync($"ClientrError{context.HttpContext.Response.StatusCode}");
     }
 }
예제 #10
0
파일: AppManager.cs 프로젝트: jclown/test
        /// <summary>
        /// 状态码Startup.Configure:app.UseStatusCodePages(async context => Modobay.AppManager.HandleExceptionAsync(context));
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static Task HandleExceptionAsync(StatusCodeContext context)
        {
            var err = JsonConvert.SerializeObject(new Modobay.Api.ExceptionResultDto()
            {
                ErrorCode    = context.HttpContext.Response.StatusCode.ToString(),
                ErrorMessage = context.HttpContext.Connection?.RemoteIpAddress.ToString(),
                RequestId    = context.HttpContext.TraceIdentifier
            });

            context.HttpContext.Response.ContentType = "application/json";
            return(context.HttpContext.Response.WriteAsync(err));
        }
예제 #11
0
        public async Task Process(StatusCodeContext context)
        {
            var statusCode = context.HttpContext.Response.StatusCode;

            if (IsApiCall(context.HttpContext))
            {
                await OnApiCallAsync(context, statusCode);
            }
            else
            {
                await OnWebCallAsync(context, statusCode);
            }
        }
예제 #12
0
            static async Task HandleAsync(StatusCodeContext context)
            {
                var response = context.HttpContext.Response;

                if (response.StatusCode < 500)
                {
                    await response.WriteAsync($"Client error ({response.StatusCode})");
                }
                else
                {
                    await response.WriteAsync($"Server error ({response.StatusCode})");
                }
            }
예제 #13
0
        private async Task HandleFaultStatusCode(StatusCodeContext context)
        {
            var statusCode            = context.HttpContext.Response.StatusCode;
            var statusCodeName        = Enum.GetName(typeof(HttpStatusCode), (HttpStatusCode)statusCode);
            var statusCodeDescription = statusCodeName.TryTransform(x => $"{statusCode} {Regex.Replace(x, "([A-Z])", " $1").Trim()}");

            var resultWriter = mProvider.Configuration.Configuration.CommunicationStrategy ?? new JsonCommunicationStrategy();
            var result       = new Result
            {
                HasError         = true,
                ErrorDescription = statusCodeDescription
            };

            context.HttpContext.Response.ContentType = resultWriter.ContentType;

            await resultWriter.WriteAsync(context.HttpContext.Response.Body, mProvider.Configuration.Configuration.Encoding ?? Encoding.UTF8, result);
        }
예제 #14
0
        public static Task HttpCodeMessage(this StatusCodeContext context)
        {
            context.HttpContext.Response.ContentType = ContentType;

            switch (context.HttpContext.Response.StatusCode)
            {
            case StatusCodes.Status401Unauthorized: return(Unauthorized(context));

            case StatusCodes.Status403Forbidden: return(Forbidden(context));

            case StatusCodes.Status404NotFound: return(NotFound(context));

            case StatusCodes.Status500InternalServerError: return(InternalServerError(context));
            }

            return(Task.CompletedTask);
        }
        /// <summary>
        /// Re-executes the HTTP request with new values.
        /// </summary>
        /// <param name="context">Status code context.</param>
        /// <param name="originalPath">Original path.</param>
        /// <param name="originalQueryString">Original query string value.</param>
        /// <param name="newPath">New path.</param>
        /// <param name="newQueryString">New query string value.</param>
        /// <returns></returns>
        private static async Task ReExecuteRequest(StatusCodeContext context, PathString originalPath, QueryString originalQueryString, PathString newPath, QueryString newQueryString)
        {
            // An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
            // the endpoint and route values to ensure things are re-calculated.
            context.HttpContext.SetEndpoint(endpoint: null);
            var routeValuesFeature = context.HttpContext.Features.Get <IRouteValuesFeature>();

            routeValuesFeature?.RouteValues?.Clear();

            context.HttpContext.Request.Path        = newPath;
            context.HttpContext.Request.QueryString = newQueryString;

            try
            {
                await context.Next(context.HttpContext);
            }
            finally
            {
                context.HttpContext.Request.QueryString = originalQueryString;
                context.HttpContext.Request.Path        = originalPath;
                context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(null !);
            }
        }
        private static async Task Handle(StatusCodeContext context, string _newPath)
        {
            var newPath        = new PathString(_newPath);
            var newQueryString = QueryString.Empty;

            var originalPath        = context.HttpContext.Request.Path;
            var originalQueryString = context.HttpContext.Request.QueryString;

            // Store the original paths so the app can check it.
            context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
            {
                OriginalPathBase    = context.HttpContext.Request.PathBase.Value,
                OriginalPath        = originalPath.Value,
                OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
            });

            // An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
            // the endpoint and route values to ensure things are re-calculated.
            context.HttpContext.SetEndpoint(endpoint: null);
            var routeValuesFeature = context.HttpContext.Features.Get <IRouteValuesFeature>();

            routeValuesFeature?.RouteValues?.Clear();
            context.HttpContext.Request.Path        = newPath;
            context.HttpContext.Request.QueryString = newQueryString;

            try
            {
                await context.Next(context.HttpContext);
            }
            finally
            {
                context.HttpContext.Request.QueryString = originalQueryString;
                context.HttpContext.Request.Path        = originalPath;
                context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(null);
            }
        }
예제 #17
0
 static Task HandleAsync(StatusCodeContext context)
 => context.HttpContext.Response.WriteAsync("Error occurred!");
예제 #18
0
        protected virtual async Task OnWebCallAsync(StatusCodeContext context, int statusCode)
        {
            var appConfig = EngineContext.Current.Resolve <IOptions <AppConfig> >()?.Value;

            var pathFormat = appConfig?.ErrorPage?.DefaultRedirect;
            var mode       = ResponseMode.Redirect;

            var httpErrorConfig = appConfig?.ErrorPage?.HttpErrors?.FirstOrDefault(it => it.StatusCode == statusCode);

            if (httpErrorConfig != null)
            {
                pathFormat = httpErrorConfig.Path;
                mode       = httpErrorConfig.Mode;
            }

            if (string.IsNullOrEmpty(pathFormat))
            {
                context.HttpContext.Response.ContentType = "text/html;charset=utf-8";
                context.HttpContext.Response.StatusCode  = 200;
                await context.HttpContext.Response.WriteAsync($"系统不想理你,并扔了一个 {statusCode} 页面给你。");
            }
            else
            {
                var originalPath        = context.HttpContext.Request.Path;
                var originalQueryString = context.HttpContext.Request.QueryString;

                //替换 ?? 为 #question_mark#
                pathFormat = pathFormat.Replace("??", "__question_mark__");

                var newPath = new PathString(string.Format(CultureInfo.InvariantCulture,
                                                           pathFormat,
                                                           context.HttpContext.Response.StatusCode,
                                                           originalPath.Value,
                                                           originalQueryString.HasValue ? originalQueryString.Value : null));

                //替换 #question_mark# 为 ?
                var newPath1 = newPath.ToString().Replace("__question_mark__", "?");

                if (mode == ResponseMode.Redirect)
                {
                    context.HttpContext.Response.Redirect(newPath1);
                    return;
                }

                context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(new StatusCodeReExecuteFeature()
                {
                    OriginalPathBase    = context.HttpContext.Request.PathBase.Value,
                    OriginalPath        = originalPath.Value,
                    OriginalQueryString = originalQueryString.HasValue ? originalQueryString.Value : null,
                });

                context.HttpContext.SetEndpoint(endpoint: null);
                var routeValuesFeature = context.HttpContext.Features.Get <IRouteValuesFeature>();
                routeValuesFeature?.RouteValues?.Clear();

                context.HttpContext.Request.Path = new PathString(newPath1);
                try
                {
                    await context.Next(context.HttpContext);
                }
                finally
                {
                    context.HttpContext.Request.QueryString = originalQueryString;
                    context.HttpContext.Request.Path        = originalPath;
                    context.HttpContext.Features.Set <IStatusCodeReExecuteFeature>(null);
                }
            }
        }
예제 #19
0
파일: Startup.cs 프로젝트: Lulalaby/SlimGet
 private Task RenderStatusCode(StatusCodeContext ctx)
 => this.RunHandlerAsync(ctx.HttpContext);