public async Task InvokeAsync(HttpContext context, RequestDelegate next) { // TODO: It would be possible to redirect to the installer here in debug mode while // still showing the error. This would be a lot more friendly than just the YSOD. // We could also then have a different installer view for when package migrations fails // and to retry each one individually. Perhaps this can happen in the future. if (_runtimeState.Level == RuntimeLevel.BootFailed) { // short circuit if (_hostingEnvironment.IsDebugMode) { BootFailedException.Rethrow(_runtimeState.BootFailedException); } else { // Print a nice error page context.Response.Clear(); context.Response.StatusCode = 500; IFileInfo?fileInfo = GetBootErrorFileInfo(); if (fileInfo is not null) { using var sr = new StreamReader(fileInfo.CreateReadStream(), Encoding.UTF8); await context.Response.WriteAsync(await sr.ReadToEndAsync(), Encoding.UTF8); } } } else { await next(context); } }
public async Task InvokeAsync(HttpContext context, RequestDelegate next) { // TODO: It would be possible to redirect to the installer here in debug mode while // still showing the error. This would be a lot more friendly than just the YSOD. // We could also then have a different installer view for when package migrations fails // and to retry each one individually. Perhaps this can happen in the future. if (_runtimeState.Level == RuntimeLevel.BootFailed) { // short circuit if (_hostingEnvironment.IsDebugMode) { BootFailedException.Rethrow(_runtimeState.BootFailedException); } else // Print a nice error page { context.Response.Clear(); context.Response.StatusCode = 500; var file = GetBootErrorFileName(); var viewContent = await File.ReadAllTextAsync(file); await context.Response.WriteAsync(viewContent, Encoding.UTF8); } } else { await next(context); } }
/// <inheritdoc /> public void Init(HttpApplication context) { try { // using the service locator here - no other way, really Module = Current.Factory.GetInstance <TModule>(); } catch { // if GetInstance fails, it may be because of a boot error, in // which case that is the error we actually want to report IRuntimeState runtimeState = null; try { runtimeState = Current.Factory.GetInstance <IRuntimeState>(); } catch { /* don't make it worse */ } if (runtimeState?.BootFailedException != null) { BootFailedException.Rethrow(runtimeState.BootFailedException); } // else... throw what we have throw; } // initialize Module.Init(context); }
/// <inheritdoc /> public void Init(HttpApplication context) { try { // using the service locator here - no other way, really Module = Current.Factory.GetInstance <TModule>(); } catch { // if GetInstance fails, it may be because of a boot error, in // which case that is the error we actually want to report IRuntimeState runtimeState = null; try { runtimeState = Current.Factory.GetInstance <IRuntimeState>(); } catch { /* don't make it worse */ } if (runtimeState?.BootFailedException != null) { // if we throw the exception here the HttpApplication.Application_Error method will never be hit // and our custom error page will not be shown, so we need to wait for the request to begin // before we throw the exception. context.BeginRequest += (sender, args) => { BootFailedException.Rethrow(runtimeState.BootFailedException); }; return; } // else... throw what we have throw; } // initialize Module.Init(context); }
/// <summary> /// Initialize the module, this will trigger for each new application /// and there may be more than 1 application per application domain /// </summary> /// <param name="app"></param> public void Init(HttpApplication app) { if (_runtime.Level == RuntimeLevel.BootFailed) { // there's nothing we can do really app.BeginRequest += (sender, args) => { // would love to avoid throwing, and instead display a customized Umbraco 500 // page - however if we don't throw here, something else might go wrong, and // it's this later exception that would be reported. could not figure out how // to prevent it, either with httpContext.Response.End() or .ApplicationInstance // .CompleteRequest() // also, if something goes wrong with our DI setup, the logging subsystem may // not even kick in, so here we try to give as much detail as possible BootFailedException.Rethrow(Core.Composing.Current.RuntimeState.BootFailedException); }; return; } app.BeginRequest += (sender, e) => { var httpContext = ((HttpApplication)sender).Context; LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId); _logger.Verbose <UmbracoModule>("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, httpContext.Request.Url); BeginRequest(new HttpContextWrapper(httpContext)); }; //disable asp.net headers (security) // This is the correct place to modify headers according to MS: // https://our.umbraco.com/forum/umbraco-7/using-umbraco-7/65241-Heap-error-from-header-manipulation?p=0#comment220889 app.PostReleaseRequestState += (sender, args) => { var httpContext = ((HttpApplication)sender).Context; try { httpContext.Response.Headers.Remove("Server"); //this doesn't normally work since IIS sets it but we'll keep it here anyways. httpContext.Response.Headers.Remove("X-Powered-By"); httpContext.Response.Headers.Remove("X-AspNet-Version"); httpContext.Response.Headers.Remove("X-AspNetMvc-Version"); } catch (PlatformNotSupportedException) { // can't remove headers this way on IIS6 or cassini. } }; app.PostAuthenticateRequest += (sender, e) => { var httpContext = ((HttpApplication)sender).Context; //ensure the thread culture is set httpContext.User?.Identity?.EnsureCulture(); }; app.PostResolveRequestCache += (sender, e) => { var httpContext = ((HttpApplication)sender).Context; ProcessRequest(new HttpContextWrapper(httpContext)); }; app.EndRequest += (sender, args) => { var httpContext = ((HttpApplication)sender).Context; if (Current.UmbracoContext != null && Current.UmbracoContext.IsFrontEndUmbracoRequest) { LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId); _logger.Verbose <UmbracoModule>("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, httpContext.Request.Url, DateTime.Now.Subtract(Current.UmbracoContext.ObjectCreated).TotalMilliseconds); } UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext, new HttpContextWrapper(httpContext))); DisposeHttpContextItems(httpContext); }; }