Replaced usages of HttpContext.Items with usages of IRequestCache
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -101,5 +102,9 @@ namespace Umbraco.Core.Cache
|
||||
var compiled = new Regex(regex, RegexOptions.Compiled);
|
||||
_items.RemoveAll(kvp => compiled.IsMatch(kvp.Key));
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => _items.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,5 +171,20 @@ namespace Umbraco.Core.Cache
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
||||
{
|
||||
if (!TryGetContextItems(out var items))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (DictionaryEntry item in items)
|
||||
{
|
||||
yield return new KeyValuePair<string, object>(item.Key.ToString(), item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
public interface IRequestCache : IAppCache
|
||||
public interface IRequestCache : IAppCache, IEnumerable<KeyValuePair<string, object>>
|
||||
{
|
||||
bool Set(string key, object value);
|
||||
bool Remove(string key);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -84,5 +85,9 @@ namespace Umbraco.Core.Cache
|
||||
/// <inheritdoc />
|
||||
public virtual void ClearByRegex(string regex)
|
||||
{ }
|
||||
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => new Dictionary<string, object>().GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,11 +439,6 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
|
||||
return (IPublishedContent) appCache.Get(key, () => (new XmlPublishedContent(node, isPreviewing, appCache, contentTypeCache, variationContextAccessor)).CreateModel(Current.PublishedModelFactory));
|
||||
}
|
||||
|
||||
public static void ClearRequest()
|
||||
{
|
||||
Current.AppCaches.RequestCache.ClearByKey(CacheKeyPrefix);
|
||||
}
|
||||
|
||||
private const string CacheKeyPrefix = "CONTENTCACHE_XMLPUBLISHEDCONTENT_";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ namespace Umbraco.Tests.Routing
|
||||
logger,
|
||||
null, // FIXME: PublishedRouter complexities...
|
||||
Mock.Of<IUmbracoContextFactory>(),
|
||||
new RoutableDocumentFilter(globalSettings, IOHelper)
|
||||
new RoutableDocumentFilter(globalSettings, IOHelper),
|
||||
AppCaches.RequestCache
|
||||
);
|
||||
|
||||
runtime.Level = RuntimeLevel.Run;
|
||||
|
||||
@@ -8,7 +8,6 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Tests.Testing.Objects.Accessors;
|
||||
using Umbraco.Web;
|
||||
@@ -39,7 +38,7 @@ namespace Umbraco.Tests.Security
|
||||
|
||||
var runtime = Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Install);
|
||||
var mgr = new BackOfficeCookieManager(
|
||||
Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbracoContext), runtime, TestObjects.GetGlobalSettings(), TestHelper.IOHelper);
|
||||
Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbracoContext), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache);
|
||||
|
||||
var result = mgr.ShouldAuthenticateRequest(Mock.Of<IOwinContext>(), new Uri("http://localhost/umbraco"));
|
||||
|
||||
@@ -58,7 +57,7 @@ namespace Umbraco.Tests.Security
|
||||
new TestVariationContextAccessor(), IOHelper);
|
||||
|
||||
var runtime = Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run);
|
||||
var mgr = new BackOfficeCookieManager(Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbCtx), runtime, TestObjects.GetGlobalSettings(), TestHelper.IOHelper);
|
||||
var mgr = new BackOfficeCookieManager(Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbCtx), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache);
|
||||
|
||||
var request = new Mock<OwinRequest>();
|
||||
request.Setup(owinRequest => owinRequest.Uri).Returns(new Uri("http://localhost/umbraco"));
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
protected override void Compose()
|
||||
{
|
||||
base.Compose();
|
||||
base.Compose();
|
||||
|
||||
Composition.RegisterUnique<IPublishedValueFallback, PublishedValueFallback>();
|
||||
Composition.RegisterUnique<IProfilingLogger, ProfilingLogger>();
|
||||
|
||||
@@ -28,22 +28,14 @@ namespace Umbraco.Web
|
||||
public class BatchedDatabaseServerMessenger : DatabaseServerMessenger
|
||||
{
|
||||
private readonly IUmbracoDatabaseFactory _databaseFactory;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
public BatchedDatabaseServerMessenger(
|
||||
IRuntimeState runtime,
|
||||
IUmbracoDatabaseFactory databaseFactory,
|
||||
IScopeProvider scopeProvider,
|
||||
ISqlContext sqlContext,
|
||||
IProfilingLogger proflog,
|
||||
DatabaseServerMessengerOptions options,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
CacheRefresherCollection cacheRefreshers,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
IRuntimeState runtime, IUmbracoDatabaseFactory databaseFactory, IScopeProvider scopeProvider, ISqlContext sqlContext, IProfilingLogger proflog, DatabaseServerMessengerOptions options, IHostingEnvironment hostingEnvironment, CacheRefresherCollection cacheRefreshers, IRequestCache requestCache)
|
||||
: base(runtime, scopeProvider, sqlContext, proflog, true, options, hostingEnvironment, cacheRefreshers)
|
||||
{
|
||||
_databaseFactory = databaseFactory;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
// invoked by DatabaseServerRegistrarAndMessengerComponent
|
||||
@@ -112,24 +104,18 @@ namespace Umbraco.Web
|
||||
|
||||
protected ICollection<RefreshInstructionEnvelope> GetBatch(bool create)
|
||||
{
|
||||
// try get the http context from the UmbracoContext, we do this because in the case we are launching an async
|
||||
// thread and we know that the cache refreshers will execute, we will ensure the UmbracoContext and therefore we
|
||||
// can get the http context from it
|
||||
var httpContext = (_httpContextAccessor.HttpContext)
|
||||
// if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext
|
||||
// wasn't ensured at the beginning of the thread. We can try to see if the HttpContext.Current is available which might be
|
||||
// the case if the asp.net synchronization context has kicked in
|
||||
?? (HttpContext.Current == null ? null : new HttpContextWrapper(HttpContext.Current));
|
||||
|
||||
// if no context was found, return null - we cannot not batch
|
||||
if (httpContext == null) return null;
|
||||
|
||||
var key = typeof (BatchedDatabaseServerMessenger).Name;
|
||||
|
||||
if (!_requestCache.IsAvailable) return null;
|
||||
|
||||
// no thread-safety here because it'll run in only 1 thread (request) at a time
|
||||
var batch = (ICollection<RefreshInstructionEnvelope>)httpContext.Items[key];
|
||||
var batch = (ICollection<RefreshInstructionEnvelope>)_requestCache.Get(key);
|
||||
if (batch == null && create)
|
||||
httpContext.Items[key] = batch = new List<RefreshInstructionEnvelope>();
|
||||
{
|
||||
batch = new List<RefreshInstructionEnvelope>();
|
||||
_requestCache.Set(key, batch);
|
||||
}
|
||||
|
||||
return batch;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,20 +4,6 @@ namespace Umbraco.Core
|
||||
{
|
||||
public static class HttpContextExtensions
|
||||
{
|
||||
public static T GetContextItem<T>(this HttpContextBase httpContext, string key)
|
||||
{
|
||||
if (httpContext == null) return default(T);
|
||||
if (httpContext.Items[key] == null) return default(T);
|
||||
var val = httpContext.Items[key].TryConvertTo<T>();
|
||||
if (val) return val.Result;
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public static T GetContextItem<T>(this HttpContext httpContext, string key)
|
||||
{
|
||||
return new HttpContextWrapper(httpContext).GetContextItem<T>(key);
|
||||
}
|
||||
|
||||
public static string GetCurrentRequestIpAddress(this HttpContextBase httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
using System;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
internal class HttpContextUmbracoContextAccessor : IUmbracoContextAccessor
|
||||
{
|
||||
private readonly IRequestCache _requestCache;
|
||||
private const string HttpContextItemKey = "Umbraco.Web.UmbracoContext";
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public HttpContextUmbracoContextAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
public HttpContextUmbracoContextAccessor(IRequestCache requestCache)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
public IUmbracoContext UmbracoContext
|
||||
{
|
||||
get
|
||||
{
|
||||
var httpContext = _httpContextAccessor.HttpContext;
|
||||
if (httpContext == null) throw new Exception("oops:httpContext");
|
||||
return (IUmbracoContext) httpContext.Items[HttpContextItemKey];
|
||||
if (!_requestCache.IsAvailable) throw new InvalidOperationException("No request cache available");
|
||||
return (IUmbracoContext) _requestCache.Get(HttpContextItemKey);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var httpContext = _httpContextAccessor.HttpContext;
|
||||
if (httpContext == null) throw new Exception("oops:httpContext");
|
||||
httpContext.Items[HttpContextItemKey] = value;
|
||||
if (!_requestCache.IsAvailable) throw new InvalidOperationException("No request cache available");
|
||||
_requestCache.Set(HttpContextItemKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -16,12 +17,14 @@ namespace Umbraco.Web
|
||||
public abstract class HybridAccessorBase<T>
|
||||
where T : class
|
||||
{
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
// ReSharper disable StaticMemberInGenericType
|
||||
private static readonly object Locker = new object();
|
||||
private static bool _registered;
|
||||
// ReSharper restore StaticMemberInGenericType
|
||||
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
// private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
protected abstract string ItemKey { get; }
|
||||
|
||||
@@ -50,9 +53,9 @@ namespace Umbraco.Web
|
||||
}
|
||||
}
|
||||
|
||||
protected HybridAccessorBase(IHttpContextAccessor httpContextAccessor)
|
||||
protected HybridAccessorBase(IRequestCache requestCache)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
|
||||
_requestCache = requestCache ?? throw new ArgumentNullException(nameof(requestCache));
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@@ -81,20 +84,23 @@ namespace Umbraco.Web
|
||||
{
|
||||
get
|
||||
{
|
||||
var httpContext = _httpContextAccessor.HttpContext;
|
||||
if (httpContext == null) return NonContextValue;
|
||||
return (T) httpContext.Items[ItemKey];
|
||||
if (!_requestCache.IsAvailable)
|
||||
{
|
||||
return NonContextValue;
|
||||
}
|
||||
return (T) _requestCache.Get(ItemKey);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
var httpContext = _httpContextAccessor.HttpContext;
|
||||
if (httpContext == null)
|
||||
if (!_requestCache.IsAvailable)
|
||||
{
|
||||
NonContextValue = value;
|
||||
}
|
||||
else if (value == null)
|
||||
httpContext.Items.Remove(ItemKey);
|
||||
_requestCache.Remove(ItemKey);
|
||||
else
|
||||
httpContext.Items[ItemKey] = value;
|
||||
_requestCache.Set(ItemKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Events;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -6,8 +7,8 @@ namespace Umbraco.Web
|
||||
{
|
||||
protected override string ItemKey => "Umbraco.Core.Events.HybridEventMessagesAccessor";
|
||||
|
||||
public HybridEventMessagesAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
public HybridEventMessagesAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
public EventMessages EventMessages
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Web
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a hybrid <see cref="IUmbracoContextAccessor"/>.
|
||||
@@ -8,8 +10,8 @@
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HybridUmbracoContextAccessor"/> class.
|
||||
/// </summary>
|
||||
public HybridUmbracoContextAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
public HybridUmbracoContextAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
@@ -7,22 +8,22 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
/// </summary>
|
||||
public class HttpContextVariationContextAccessor : IVariationContextAccessor
|
||||
{
|
||||
public const string ContextKey = "Umbraco.Web.Models.PublishedContent.DefaultVariationContextAccessor";
|
||||
public readonly IHttpContextAccessor HttpContextAccessor;
|
||||
private readonly IRequestCache _requestCache;
|
||||
private const string _contextKey = "Umbraco.Web.Models.PublishedContent.DefaultVariationContextAccessor";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpContextVariationContextAccessor"/> class.
|
||||
/// </summary>
|
||||
public HttpContextVariationContextAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
public HttpContextVariationContextAccessor(IRequestCache requestCache)
|
||||
{
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public VariationContext VariationContext
|
||||
{
|
||||
get => (VariationContext) HttpContextAccessor.HttpContext?.Items[ContextKey];
|
||||
set => HttpContextAccessor.HttpContext.Items[ContextKey] = value;
|
||||
get => (VariationContext) _requestCache.Get(_contextKey);
|
||||
set => _requestCache.Set(_contextKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
@@ -7,8 +8,8 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
/// </summary>
|
||||
internal class HybridVariationContextAccessor : HybridAccessorBase<VariationContext>, IVariationContextAccessor
|
||||
{
|
||||
public HybridVariationContextAccessor(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
public HybridVariationContextAccessor(IRequestCache requestCache)
|
||||
: base(requestCache)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -23,4 +24,4 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
set => Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Microsoft.Owin.Security.DataHandler;
|
||||
using Microsoft.Owin.Security.DataProtection;
|
||||
using Owin;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -153,9 +154,10 @@ namespace Umbraco.Web.Security
|
||||
IGlobalSettings globalSettings,
|
||||
ISecuritySection securitySection,
|
||||
IIOHelper ioHelper,
|
||||
IRequestCache requestCache,
|
||||
IUmbracoSettingsSection umbracoSettingsSection)
|
||||
{
|
||||
return app.UseUmbracoBackOfficeCookieAuthentication(umbracoContextAccessor, runtimeState, userService, globalSettings, securitySection, ioHelper, PipelineStage.Authenticate, umbracoSettingsSection);
|
||||
return app.UseUmbracoBackOfficeCookieAuthentication(umbracoContextAccessor, runtimeState, userService, globalSettings, securitySection, ioHelper, requestCache, PipelineStage.Authenticate, umbracoSettingsSection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -179,11 +181,12 @@ namespace Umbraco.Web.Security
|
||||
IGlobalSettings globalSettings,
|
||||
ISecuritySection securitySection,
|
||||
IIOHelper ioHelper,
|
||||
IRequestCache requestCache,
|
||||
PipelineStage stage,
|
||||
IUmbracoSettingsSection umbracoSettingsSection)
|
||||
{
|
||||
//Create the default options and provider
|
||||
var authOptions = app.CreateUmbracoCookieAuthOptions(umbracoContextAccessor, globalSettings, runtimeState, securitySection, ioHelper);
|
||||
var authOptions = app.CreateUmbracoCookieAuthOptions(umbracoContextAccessor, globalSettings, runtimeState, securitySection, ioHelper, requestCache);
|
||||
|
||||
authOptions.Provider = new BackOfficeCookieAuthenticationProvider(userService, runtimeState, globalSettings, ioHelper, umbracoSettingsSection)
|
||||
{
|
||||
@@ -198,7 +201,7 @@ namespace Umbraco.Web.Security
|
||||
|
||||
};
|
||||
|
||||
return app.UseUmbracoBackOfficeCookieAuthentication(umbracoContextAccessor, runtimeState, globalSettings, securitySection, ioHelper, authOptions, stage);
|
||||
return app.UseUmbracoBackOfficeCookieAuthentication(umbracoContextAccessor, runtimeState, globalSettings, securitySection, ioHelper, requestCache, authOptions, stage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,7 +218,8 @@ namespace Umbraco.Web.Security
|
||||
/// Configurable pipeline stage
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static IAppBuilder UseUmbracoBackOfficeCookieAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, IGlobalSettings globalSettings, ISecuritySection securitySection, IIOHelper ioHelper, CookieAuthenticationOptions cookieOptions, PipelineStage stage)
|
||||
public static IAppBuilder UseUmbracoBackOfficeCookieAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, IGlobalSettings globalSettings,
|
||||
ISecuritySection securitySection, IIOHelper ioHelper, IRequestCache requestCache, CookieAuthenticationOptions cookieOptions, PipelineStage stage)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
if (runtimeState == null) throw new ArgumentNullException(nameof(runtimeState));
|
||||
@@ -225,7 +229,7 @@ namespace Umbraco.Web.Security
|
||||
if (cookieOptions.Provider is BackOfficeCookieAuthenticationProvider == false)
|
||||
throw new ArgumentException($"cookieOptions.Provider must be of type {typeof(BackOfficeCookieAuthenticationProvider)}.", nameof(cookieOptions));
|
||||
|
||||
app.UseUmbracoBackOfficeCookieAuthenticationInternal(cookieOptions, runtimeState, stage);
|
||||
app.UseUmbracoBackOfficeCookieAuthenticationInternal(cookieOptions, runtimeState, requestCache, stage);
|
||||
|
||||
//don't apply if app is not ready
|
||||
if (runtimeState.Level != RuntimeLevel.Upgrade && runtimeState.Level != RuntimeLevel.Run) return app;
|
||||
@@ -233,7 +237,7 @@ namespace Umbraco.Web.Security
|
||||
var cookieAuthOptions = app.CreateUmbracoCookieAuthOptions(
|
||||
umbracoContextAccessor, globalSettings, runtimeState, securitySection,
|
||||
//This defines the explicit path read cookies from for this middleware
|
||||
ioHelper, new[] {$"{globalSettings.Path}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds"});
|
||||
ioHelper, requestCache, new[] {$"{globalSettings.Path}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds"});
|
||||
cookieAuthOptions.Provider = cookieOptions.Provider;
|
||||
|
||||
//This is a custom middleware, we need to return the user's remaining logged in seconds
|
||||
@@ -279,7 +283,7 @@ namespace Umbraco.Web.Security
|
||||
});
|
||||
}
|
||||
|
||||
private static void UseUmbracoBackOfficeCookieAuthenticationInternal(this IAppBuilder app, CookieAuthenticationOptions options, IRuntimeState runtimeState, PipelineStage stage)
|
||||
private static void UseUmbracoBackOfficeCookieAuthenticationInternal(this IAppBuilder app, CookieAuthenticationOptions options, IRuntimeState runtimeState, IRequestCache requestCache, PipelineStage stage)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
if (runtimeState == null) throw new ArgumentNullException(nameof(runtimeState));
|
||||
@@ -290,7 +294,7 @@ namespace Umbraco.Web.Security
|
||||
if (runtimeState.Level == RuntimeLevel.Upgrade || runtimeState.Level == RuntimeLevel.Run)
|
||||
{
|
||||
//Then our custom middlewares
|
||||
app.Use(typeof(ForceRenewalCookieAuthenticationMiddleware), app, options, Current.UmbracoContextAccessor);
|
||||
app.Use(typeof(ForceRenewalCookieAuthenticationMiddleware), app, options, Current.UmbracoContextAccessor, requestCache);
|
||||
app.Use(typeof(FixWindowsAuthMiddlware));
|
||||
}
|
||||
|
||||
@@ -311,9 +315,9 @@ namespace Umbraco.Web.Security
|
||||
/// <remarks>
|
||||
/// By default this will be configured to execute on PipelineStage.Authenticate
|
||||
/// </remarks>
|
||||
public static IAppBuilder UseUmbracoBackOfficeExternalCookieAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState,IGlobalSettings globalSettings, IIOHelper ioHelper)
|
||||
public static IAppBuilder UseUmbracoBackOfficeExternalCookieAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState,IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache)
|
||||
{
|
||||
return app.UseUmbracoBackOfficeExternalCookieAuthentication(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, PipelineStage.Authenticate);
|
||||
return app.UseUmbracoBackOfficeExternalCookieAuthentication(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache, PipelineStage.Authenticate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -329,7 +333,7 @@ namespace Umbraco.Web.Security
|
||||
/// <returns></returns>
|
||||
public static IAppBuilder UseUmbracoBackOfficeExternalCookieAuthentication(this IAppBuilder app,
|
||||
IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState,
|
||||
IGlobalSettings globalSettings, IIOHelper ioHelper, PipelineStage stage)
|
||||
IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache, PipelineStage stage)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
if (runtimeState == null) throw new ArgumentNullException(nameof(runtimeState));
|
||||
@@ -342,7 +346,7 @@ namespace Umbraco.Web.Security
|
||||
CookieName = Constants.Security.BackOfficeExternalCookieName,
|
||||
ExpireTimeSpan = TimeSpan.FromMinutes(5),
|
||||
//Custom cookie manager so we can filter requests
|
||||
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper),
|
||||
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache),
|
||||
CookiePath = "/",
|
||||
CookieSecure = globalSettings.UseHttps ? CookieSecureOption.Always : CookieSecureOption.SameAsRequest,
|
||||
CookieHttpOnly = true,
|
||||
@@ -369,9 +373,9 @@ namespace Umbraco.Web.Security
|
||||
/// <remarks>
|
||||
/// By default this will be configured to execute on PipelineStage.PostAuthenticate
|
||||
/// </remarks>
|
||||
public static IAppBuilder UseUmbracoPreviewAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, IGlobalSettings globalSettings, ISecuritySection securitySettings, IIOHelper ioHelper)
|
||||
public static IAppBuilder UseUmbracoPreviewAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, IGlobalSettings globalSettings, ISecuritySection securitySettings, IIOHelper ioHelper, IRequestCache requestCache)
|
||||
{
|
||||
return app.UseUmbracoPreviewAuthentication(umbracoContextAccessor, runtimeState, globalSettings, securitySettings, ioHelper, PipelineStage.PostAuthenticate);
|
||||
return app.UseUmbracoPreviewAuthentication(umbracoContextAccessor, runtimeState, globalSettings, securitySettings, ioHelper, requestCache, PipelineStage.PostAuthenticate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -389,11 +393,11 @@ namespace Umbraco.Web.Security
|
||||
/// This ensures that during a preview request that the back office use is also Authenticated and that the back office Identity
|
||||
/// is added as a secondary identity to the current IPrincipal so it can be used to Authorize the previewed document.
|
||||
/// </remarks>
|
||||
public static IAppBuilder UseUmbracoPreviewAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, IGlobalSettings globalSettings, ISecuritySection securitySettings, IIOHelper ioHelper, PipelineStage stage)
|
||||
public static IAppBuilder UseUmbracoPreviewAuthentication(this IAppBuilder app, IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtimeState, IGlobalSettings globalSettings, ISecuritySection securitySettings, IIOHelper ioHelper, IRequestCache requestCache, PipelineStage stage)
|
||||
{
|
||||
if (runtimeState.Level != RuntimeLevel.Run) return app;
|
||||
|
||||
var authOptions = app.CreateUmbracoCookieAuthOptions(umbracoContextAccessor, globalSettings, runtimeState, securitySettings, ioHelper);
|
||||
var authOptions = app.CreateUmbracoCookieAuthOptions(umbracoContextAccessor, globalSettings, runtimeState, securitySettings, ioHelper, requestCache);
|
||||
app.Use(typeof(PreviewAuthenticationMiddleware), authOptions, Current.Configs.Global(), ioHelper);
|
||||
|
||||
// This middleware must execute at least on PostAuthentication, by default it is on Authorize
|
||||
@@ -424,7 +428,7 @@ namespace Umbraco.Web.Security
|
||||
/// <returns></returns>
|
||||
public static UmbracoBackOfficeCookieAuthOptions CreateUmbracoCookieAuthOptions(this IAppBuilder app,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IGlobalSettings globalSettings, IRuntimeState runtimeState, ISecuritySection securitySettings, IIOHelper ioHelper, string[] explicitPaths = null)
|
||||
IGlobalSettings globalSettings, IRuntimeState runtimeState, ISecuritySection securitySettings, IIOHelper ioHelper, IRequestCache requestCache, string[] explicitPaths = null)
|
||||
{
|
||||
//this is how aspnet wires up the default AuthenticationTicket protector so we'll use the same code
|
||||
var ticketDataFormat = new TicketDataFormat(
|
||||
@@ -439,7 +443,8 @@ namespace Umbraco.Web.Security
|
||||
globalSettings,
|
||||
runtimeState,
|
||||
ticketDataFormat,
|
||||
ioHelper);
|
||||
ioHelper,
|
||||
requestCache);
|
||||
|
||||
return authOptions;
|
||||
}
|
||||
|
||||
@@ -169,18 +169,6 @@ namespace Umbraco.Web.Security
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will force ticket renewal in the OWIN pipeline
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool RenewUmbracoAuthTicket(this HttpContext http)
|
||||
{
|
||||
if (http == null) throw new ArgumentNullException("http");
|
||||
http.Items[Constants.Security.ForceReAuthFlag] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns the number of seconds the user has until their auth session times out
|
||||
/// </summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Web;
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Infrastructure;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Security;
|
||||
@@ -24,19 +25,21 @@ namespace Umbraco.Web.Security
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly IRequestCache _requestCache;
|
||||
private readonly string[] _explicitPaths;
|
||||
private readonly string _getRemainingSecondsPath;
|
||||
|
||||
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper)
|
||||
: this(umbracoContextAccessor, runtime, globalSettings, ioHelper,null)
|
||||
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache)
|
||||
: this(umbracoContextAccessor, runtime, globalSettings, ioHelper,requestCache, null)
|
||||
{ }
|
||||
|
||||
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IEnumerable<string> explicitPaths)
|
||||
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache, IEnumerable<string> explicitPaths)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_runtime = runtime;
|
||||
_globalSettings = globalSettings;
|
||||
_ioHelper = ioHelper;
|
||||
_requestCache = requestCache;
|
||||
_explicitPaths = explicitPaths?.ToArray();
|
||||
_getRemainingSecondsPath = $"{globalSettings.Path}/backoffice/UmbracoApi/Authentication/GetRemainingTimeoutSeconds";
|
||||
}
|
||||
@@ -89,8 +92,6 @@ namespace Umbraco.Web.Security
|
||||
return false;
|
||||
|
||||
var request = owinContext.Request;
|
||||
var httpContext = owinContext.TryGetHttpContext();
|
||||
|
||||
//check the explicit paths
|
||||
if (_explicitPaths != null)
|
||||
{
|
||||
@@ -102,7 +103,7 @@ namespace Umbraco.Web.Security
|
||||
|
||||
if (//check the explicit flag
|
||||
(checkForceAuthTokens && owinContext.Get<bool?>(Constants.Security.ForceReAuthFlag) != null)
|
||||
|| (checkForceAuthTokens && httpContext.Success && httpContext.Result.Items[Constants.Security.ForceReAuthFlag] != null)
|
||||
|| (checkForceAuthTokens && _requestCache.IsAvailable && _requestCache.Get(Constants.Security.ForceReAuthFlag) != null)
|
||||
//check back office
|
||||
|| request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper)
|
||||
//check installer
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.Owin.Security;
|
||||
using Microsoft.Owin.Security.Cookies;
|
||||
using Microsoft.Owin.Security.Infrastructure;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Web.Security
|
||||
@@ -13,10 +14,12 @@ namespace Umbraco.Web.Security
|
||||
internal class ForceRenewalCookieAuthenticationHandler : AuthenticationHandler<CookieAuthenticationOptions>
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
public ForceRenewalCookieAuthenticationHandler(IUmbracoContextAccessor umbracoContextAccessor)
|
||||
public ForceRenewalCookieAuthenticationHandler(IUmbracoContextAccessor umbracoContextAccessor, IRequestCache requestCache)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -68,9 +71,8 @@ namespace Umbraco.Web.Security
|
||||
//This is auth'd normally, so OWIN will naturally take care of the cookie renewal
|
||||
if (normalAuthUrl) return Task.FromResult(0);
|
||||
|
||||
var httpCtx = Context.TryGetHttpContext();
|
||||
//check for the special flag in either the owin or http context
|
||||
var shouldRenew = Context.Get<bool?>(Constants.Security.ForceReAuthFlag) != null || (httpCtx.Success && httpCtx.Result.Items[Constants.Security.ForceReAuthFlag] != null);
|
||||
var shouldRenew = Context.Get<bool?>(Constants.Security.ForceReAuthFlag) != null || (_requestCache.IsAvailable && _requestCache.Get(Constants.Security.ForceReAuthFlag) != null);
|
||||
|
||||
if (shouldRenew)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Owin.Security.Cookies;
|
||||
using Microsoft.Owin.Security.Infrastructure;
|
||||
using Owin;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Web.Security
|
||||
{
|
||||
@@ -11,19 +12,22 @@ namespace Umbraco.Web.Security
|
||||
internal class ForceRenewalCookieAuthenticationMiddleware : CookieAuthenticationMiddleware
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
public ForceRenewalCookieAuthenticationMiddleware(
|
||||
OwinMiddleware next,
|
||||
IAppBuilder app,
|
||||
UmbracoBackOfficeCookieAuthOptions options,
|
||||
IUmbracoContextAccessor umbracoContextAccessor) : base(next, app, options)
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IRequestCache requestCache) : base(next, app, options)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
protected override AuthenticationHandler<CookieAuthenticationOptions> CreateHandler()
|
||||
{
|
||||
return new ForceRenewalCookieAuthenticationHandler(_umbracoContextAccessor);
|
||||
return new ForceRenewalCookieAuthenticationHandler(_umbracoContextAccessor, _requestCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.Owin;
|
||||
using Microsoft.Owin.Security;
|
||||
using Microsoft.Owin.Security.Cookies;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -23,7 +24,8 @@ namespace Umbraco.Web.Security
|
||||
IGlobalSettings globalSettings,
|
||||
IRuntimeState runtimeState,
|
||||
ISecureDataFormat<AuthenticationTicket> secureDataFormat,
|
||||
IIOHelper ioHelper)
|
||||
IIOHelper ioHelper,
|
||||
IRequestCache requestCache)
|
||||
{
|
||||
var secureDataFormat1 = secureDataFormat ?? throw new ArgumentNullException(nameof(secureDataFormat));
|
||||
LoginTimeoutMinutes = globalSettings.TimeOutInMinutes;
|
||||
@@ -40,7 +42,7 @@ namespace Umbraco.Web.Security
|
||||
TicketDataFormat = new UmbracoSecureDataFormat(LoginTimeoutMinutes, secureDataFormat1);
|
||||
|
||||
//Custom cookie manager so we can filter requests
|
||||
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, explicitPaths);
|
||||
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache, explicitPaths);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Owin;
|
||||
using Owin;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -34,6 +35,7 @@ namespace Umbraco.Web
|
||||
protected UmbracoMapper Mapper => Current.Mapper;
|
||||
protected IIpResolver IpResolver => Current.IpResolver;
|
||||
protected IIOHelper IOHelper => Current.IOHelper;
|
||||
protected IRequestCache RequestCache => Current.AppCaches.RequestCache;
|
||||
|
||||
/// <summary>
|
||||
/// Main startup method
|
||||
@@ -102,9 +104,9 @@ namespace Umbraco.Web
|
||||
// Ensure owin is configured for Umbraco back office authentication.
|
||||
// Front-end OWIN cookie configuration must be declared after this code.
|
||||
app
|
||||
.UseUmbracoBackOfficeCookieAuthentication(UmbracoContextAccessor, RuntimeState, Services.UserService, GlobalSettings, UmbracoSettings.Security, IOHelper, PipelineStage.Authenticate, UmbracoSettings)
|
||||
.UseUmbracoBackOfficeExternalCookieAuthentication(UmbracoContextAccessor, RuntimeState, GlobalSettings, IOHelper, PipelineStage.Authenticate)
|
||||
.UseUmbracoPreviewAuthentication(UmbracoContextAccessor, RuntimeState, GlobalSettings, UmbracoSettings.Security, IOHelper, PipelineStage.Authorize);
|
||||
.UseUmbracoBackOfficeCookieAuthentication(UmbracoContextAccessor, RuntimeState, Services.UserService, GlobalSettings, UmbracoSettings.Security, IOHelper, RequestCache, PipelineStage.Authenticate, UmbracoSettings)
|
||||
.UseUmbracoBackOfficeExternalCookieAuthentication(UmbracoContextAccessor, RuntimeState, GlobalSettings, IOHelper, RequestCache, PipelineStage.Authenticate)
|
||||
.UseUmbracoPreviewAuthentication(UmbracoContextAccessor, RuntimeState, GlobalSettings, UmbracoSettings.Security, IOHelper, RequestCache, PipelineStage.Authorize);
|
||||
}
|
||||
|
||||
public static event EventHandler<OwinMiddlewareConfiguredEventArgs> MiddlewareConfigured;
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -38,6 +39,7 @@ namespace Umbraco.Web
|
||||
private readonly IPublishedRouter _publishedRouter;
|
||||
private readonly IUmbracoContextFactory _umbracoContextFactory;
|
||||
private readonly RoutableDocumentFilter _routableDocumentLookup;
|
||||
private readonly IRequestCache _requestCache;
|
||||
|
||||
public UmbracoInjectedModule(
|
||||
IGlobalSettings globalSettings,
|
||||
@@ -45,7 +47,8 @@ namespace Umbraco.Web
|
||||
ILogger logger,
|
||||
IPublishedRouter publishedRouter,
|
||||
IUmbracoContextFactory umbracoContextFactory,
|
||||
RoutableDocumentFilter routableDocumentLookup)
|
||||
RoutableDocumentFilter routableDocumentLookup,
|
||||
IRequestCache requestCache)
|
||||
{
|
||||
_globalSettings = globalSettings;
|
||||
_runtime = runtime;
|
||||
@@ -53,6 +56,7 @@ namespace Umbraco.Web
|
||||
_publishedRouter = publishedRouter;
|
||||
_umbracoContextFactory = umbracoContextFactory;
|
||||
_routableDocumentLookup = routableDocumentLookup;
|
||||
_requestCache = requestCache;
|
||||
}
|
||||
|
||||
#region HttpModule event handlers
|
||||
@@ -305,15 +309,15 @@ namespace Umbraco.Web
|
||||
/// Any object that is in the HttpContext.Items collection that is IDisposable will get disposed on the end of the request
|
||||
/// </summary>
|
||||
/// <param name="http"></param>
|
||||
private void DisposeHttpContextItems(HttpContext http)
|
||||
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<object>();
|
||||
foreach (DictionaryEntry i in http.Items)
|
||||
var keys = new HashSet<string>();
|
||||
foreach (var i in requestCache)
|
||||
{
|
||||
if (i.Value is IDisposeOnRequestEnd || i.Key is IDisposeOnRequestEnd)
|
||||
{
|
||||
@@ -325,7 +329,7 @@ namespace Umbraco.Web
|
||||
{
|
||||
try
|
||||
{
|
||||
http.Items[k].DisposeIfDisposable();
|
||||
requestCache.Get(k).DisposeIfDisposable();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -376,7 +380,7 @@ namespace Umbraco.Web
|
||||
{
|
||||
var httpContext = ((HttpApplication) sender).Context;
|
||||
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, Current.AppCaches.RequestCache);
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache);
|
||||
|
||||
_logger.Verbose<UmbracoModule>("Begin request [{HttpRequestId}]: {RequestUrl}", httpRequestId, httpContext.Request.Url);
|
||||
BeginRequest(new HttpContextWrapper(httpContext));
|
||||
@@ -421,14 +425,14 @@ namespace Umbraco.Web
|
||||
|
||||
if (Current.UmbracoContext != null && Current.UmbracoContext.IsFrontEndUmbracoRequest)
|
||||
{
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, Current.AppCaches.RequestCache);
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId, _requestCache);
|
||||
|
||||
_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);
|
||||
DisposeRequestCacheItems(httpContext, _requestCache);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user