diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs
index a43094a8f9..bce4c2430e 100644
--- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs
+++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs
@@ -27,8 +27,6 @@ namespace Umbraco.Extensions
return runtime.State.Level > RuntimeLevel.BootFailed;
}
-
-
///
/// Start Umbraco
///
@@ -38,27 +36,19 @@ namespace Umbraco.Extensions
{
if (app == null) throw new ArgumentNullException(nameof(app));
- if (app.UmbracoCanBoot())
- {
- var runtime = app.ApplicationServices.GetRequiredService();
+ var runtime = app.ApplicationServices.GetRequiredService();
- // Register a listener for application shutdown in order to terminate the runtime
- var hostLifetime = app.ApplicationServices.GetRequiredService();
- var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime);
- hostLifetime.RegisterObject(runtimeShutdown);
+ // Register a listener for application shutdown in order to terminate the runtime
+ var hostLifetime = app.ApplicationServices.GetRequiredService();
+ var runtimeShutdown = new CoreRuntimeShutdown(runtime, hostLifetime);
+ hostLifetime.RegisterObject(runtimeShutdown);
- // Register our global threadabort enricher for logging
- var threadAbortEnricher = app.ApplicationServices.GetRequiredService();
- LogContext.Push(threadAbortEnricher); // NOTE: We are not in a using clause because we are not removing it, it is on the global context
+ // Register our global threadabort enricher for logging
+ var threadAbortEnricher = app.ApplicationServices.GetRequiredService();
+ LogContext.Push(threadAbortEnricher); // NOTE: We are not in a using clause because we are not removing it, it is on the global context
- // Start the runtime!
- runtime.Start();
- }
- else
- {
- // TODO: Register simple middleware to show the error like we used to in UmbracoModule? Or maybe that's part of a UseUmbracoWebsite/backoffice type thing .. probably :)
-
- }
+ // Start the runtime!
+ runtime.Start();
return app;
}
@@ -73,15 +63,24 @@ namespace Umbraco.Extensions
{
if (app == null) throw new ArgumentNullException(nameof(app));
- app.UseMiddleware();
-
- if (!app.UmbracoCanBoot()) return app;
-
- app.UseMiddleware();
- app.UseMiddleware();
+ if (!app.UmbracoCanBoot())
+ {
+ app.UseMiddleware();
+ }
+ else
+ {
+ app.UseMiddleware();
+ app.UseMiddleware();
+ }
+
return app;
}
+ ///
+ /// Adds request based serilog enrichers to the LogContext for each request
+ ///
+ ///
+ ///
public static IApplicationBuilder UseUmbracoRequestLogging(this IApplicationBuilder app)
{
if (app == null) throw new ArgumentNullException(nameof(app));
diff --git a/src/Umbraco.Web.Common/Install/InstallController.cs b/src/Umbraco.Web.Common/Install/InstallController.cs
index 6614f2d577..a4f659379f 100644
--- a/src/Umbraco.Web.Common/Install/InstallController.cs
+++ b/src/Umbraco.Web.Common/Install/InstallController.cs
@@ -92,6 +92,10 @@ namespace Umbraco.Web.Common.Install
return View();
}
+ ///
+ /// Used to perform the redirect to the installer when the runtime level is or
+ ///
+ ///
[HttpGet]
public ActionResult Redirect()
{
diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs
index 803eb95d62..febf939d03 100644
--- a/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs
+++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestLoggingMiddleware.cs
@@ -8,6 +8,9 @@ using Umbraco.Core.Logging.Serilog.Enrichers;
namespace Umbraco.Web.Common.Middleware
{
+ ///
+ /// Adds request based serilog enrichers to the LogContext for each request
+ ///
public class UmbracoRequestLoggingMiddleware : IMiddleware
{
private readonly HttpSessionIdEnricher _sessionIdEnricher;
diff --git a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs
index e1662e834f..6cf3929e06 100644
--- a/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs
+++ b/src/Umbraco.Web.Common/Middleware/UmbracoRequestMiddleware.cs
@@ -6,6 +6,8 @@ using Umbraco.Web.Common.Lifetime;
using Umbraco.Core;
using Umbraco.Core.Logging;
using System.Threading;
+using Umbraco.Core.Cache;
+using System.Collections.Generic;
namespace Umbraco.Web.Common.Middleware
{
@@ -18,22 +20,26 @@ namespace Umbraco.Web.Common.Middleware
private readonly ILogger _logger;
private readonly IUmbracoRequestLifetimeManager _umbracoRequestLifetimeManager;
private readonly IUmbracoContextFactory _umbracoContextFactory;
+ private readonly IRequestCache _requestCache;
public UmbracoRequestMiddleware(
ILogger logger,
IUmbracoRequestLifetimeManager umbracoRequestLifetimeManager,
- IUmbracoContextFactory umbracoContextFactory)
+ IUmbracoContextFactory umbracoContextFactory,
+ IRequestCache requestCache)
{
_logger = logger;
_umbracoRequestLifetimeManager = umbracoRequestLifetimeManager;
_umbracoContextFactory = umbracoContextFactory;
+ _requestCache = requestCache;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
- // do not process if client-side request
+ var requestUri = new Uri(context.Request.GetEncodedUrl(), UriKind.RelativeOrAbsolute);
- if (new Uri(context.Request.GetEncodedUrl(), UriKind.RelativeOrAbsolute).IsClientSideRequest())
+ // do not process if client-side request
+ if (requestUri.IsClientSideRequest())
{
await next(context);
return;
@@ -43,6 +49,12 @@ namespace Umbraco.Web.Common.Middleware
try
{
+ if (umbracoContextReference.UmbracoContext.IsFrontEndUmbracoRequest)
+ {
+ LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache);
+ _logger.Verbose("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, requestUri);
+ }
+
try
{
_umbracoRequestLifetimeManager.InitRequest(context);
@@ -52,15 +64,80 @@ namespace Umbraco.Web.Common.Middleware
// try catch so we don't kill everything in all requests
_logger.Error(ex);
}
-
- await next(context);
-
- _umbracoRequestLifetimeManager.EndRequest(context);
+ finally
+ {
+ try
+ {
+ await next(context);
+ }
+ finally
+ {
+ _umbracoRequestLifetimeManager.EndRequest(context);
+ }
+ }
}
finally
{
- umbracoContextReference.Dispose();
+ if (umbracoContextReference.UmbracoContext.IsFrontEndUmbracoRequest)
+ {
+ LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache);
+ _logger.Verbose("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, requestUri, DateTime.Now.Subtract(umbracoContextReference.UmbracoContext.ObjectCreated).TotalMilliseconds);
+ }
+
+ try
+ {
+ DisposeRequestCacheItems(_logger, _requestCache, requestUri);
+ }
+ finally
+ {
+ umbracoContextReference.Dispose();
+ }
}
}
+
+ ///
+ /// Any object that is in the HttpContext.Items collection that is IDisposable will get disposed on the end of the request
+ ///
+ ///
+ ///
+ ///
+ private static void DisposeRequestCacheItems(ILogger logger, IRequestCache requestCache, Uri requestUri)
+ {
+ // do not process if client-side request
+ if (requestUri.IsClientSideRequest())
+ return;
+
+ //get a list of keys to dispose
+ var keys = new HashSet();
+ foreach (var i in requestCache)
+ {
+ if (i.Value is IDisposeOnRequestEnd || i.Key is IDisposeOnRequestEnd)
+ {
+ keys.Add(i.Key);
+ }
+ }
+ //dispose each item and key that was found as disposable.
+ foreach (var k in keys)
+ {
+ try
+ {
+ requestCache.Get(k).DisposeIfDisposable();
+ }
+ catch (Exception ex)
+ {
+ logger.Error("Could not dispose item with key " + k, ex);
+ }
+ try
+ {
+ k.DisposeIfDisposable();
+ }
+ catch (Exception ex)
+ {
+ logger.Error("Could not dispose item key " + k, ex);
+ }
+ }
+ }
+
+
}
}
diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs
index 95adb9c64e..a63e305ce2 100644
--- a/src/Umbraco.Web/UmbracoInjectedModule.cs
+++ b/src/Umbraco.Web/UmbracoInjectedModule.cs
@@ -210,11 +210,9 @@ namespace Umbraco.Web
case RuntimeLevel.Install:
case RuntimeLevel.Upgrade:
- // redirect to install
- ReportRuntime(level, "Umbraco must install or upgrade.");
- var installPath = _uriUtility.ToAbsolute(Constants.SystemDirectories.Install);
- var installUrl = $"{installPath}/?redir=true&url={HttpUtility.UrlEncode(uri.ToString())}";
- httpContext.Response.Redirect(installUrl, true);
+
+ // NOTE: We have moved the logic that was here to netcore already
+
return false; // cannot serve content
default:
@@ -222,17 +220,6 @@ namespace Umbraco.Web
}
}
- private static bool _reported;
- private static RuntimeLevel _reportedLevel;
-
- private void ReportRuntime(RuntimeLevel level, string message)
- {
- if (_reported && _reportedLevel == level) return;
- _reported = true;
- _reportedLevel = level;
- _logger.Warn(message);
- }
-
// ensures Umbraco has at least one published node
// if not, rewrites to splash and return false
// if yes, return true
@@ -309,47 +296,7 @@ namespace Umbraco.Web
}
- ///
- /// Any object that is in the HttpContext.Items collection that is IDisposable will get disposed on the end of the request
- ///
- ///
- private void DisposeRequestCacheItems(HttpContext http, IRequestCache requestCache)
- {
- // do not process if client-side request
- if (http.Request.Url.IsClientSideRequest())
- return;
-
- //get a list of keys to dispose
- var keys = new HashSet();
- foreach (var i in requestCache)
- {
- if (i.Value is IDisposeOnRequestEnd || i.Key is IDisposeOnRequestEnd)
- {
- keys.Add(i.Key);
- }
- }
- //dispose each item and key that was found as disposable.
- foreach (var k in keys)
- {
- try
- {
- requestCache.Get(k).DisposeIfDisposable();
- }
- catch (Exception ex)
- {
- _logger.Error("Could not dispose item with key " + k, ex);
- }
- try
- {
- k.DisposeIfDisposable();
- }
- catch (Exception ex)
- {
- _logger.Error("Could not dispose item key " + k, ex);
- }
- }
- }
-
+
#endregion
#region IHttpModule
@@ -365,32 +312,9 @@ namespace Umbraco.Web
{
var httpContext = ((HttpApplication) sender).Context;
- LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache);
-
- _logger.Verbose("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;
@@ -408,16 +332,7 @@ namespace Umbraco.Web
{
var httpContext = ((HttpApplication) sender).Context;
- if (Current.UmbracoContext != null && Current.UmbracoContext.IsFrontEndUmbracoRequest)
- {
- LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache);
-
- _logger.Verbose("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, httpContext.Request.Url, DateTime.Now.Subtract(Current.UmbracoContext.ObjectCreated).TotalMilliseconds);
- }
-
UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext));
-
- DisposeRequestCacheItems(httpContext, _requestCache);
};
}