Merge branch 'netcore/feature/use-request-cache-instead-of-httpcontext-items' into netcore/feature/move-files-after-umbraco-context-abstractions
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();
|
||||
}
|
||||
}
|
||||
|
||||
+21
-17
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
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; }
|
||||
|
||||
@@ -42,17 +45,16 @@ namespace Umbraco.Web
|
||||
// yes! flows with async!
|
||||
private T NonContextValue
|
||||
{
|
||||
get => (T) CallContext.LogicalGetData(ItemKey);
|
||||
get => CallContext<T>.GetData(ItemKey);
|
||||
set
|
||||
{
|
||||
if (value == null) CallContext.FreeNamedDataSlot(ItemKey);
|
||||
else CallContext.LogicalSetData(ItemKey, value);
|
||||
CallContext<T>.SetData(ItemKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected HybridAccessorBase(IHttpContextAccessor httpContextAccessor)
|
||||
protected HybridAccessorBase(IRequestCache requestCache)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
|
||||
_requestCache = requestCache ?? throw new ArgumentNullException(nameof(requestCache));
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
@@ -65,15 +67,14 @@ namespace Umbraco.Web
|
||||
var itemKey = ItemKey; // virtual
|
||||
SafeCallContext.Register(() =>
|
||||
{
|
||||
var value = CallContext.LogicalGetData(itemKey);
|
||||
CallContext.FreeNamedDataSlot(itemKey);
|
||||
var value = CallContext<T>.GetData(itemKey);
|
||||
return value;
|
||||
}, o =>
|
||||
{
|
||||
if (o == null) return;
|
||||
var value = o as T;
|
||||
if (value == null) throw new ArgumentException($"Expected type {typeof(T).FullName}, got {o.GetType().FullName}", nameof(o));
|
||||
CallContext.LogicalSetData(itemKey, value);
|
||||
CallContext<T>.SetData(itemKey, value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,20 +82,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -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
|
||||
+8
-7
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -14,14 +14,16 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IPublishedValueFallback _publishedValueFallback;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedValueFallback"/> class.
|
||||
/// </summary>
|
||||
public PublishedValueFallback(ServiceContext serviceContext, IVariationContextAccessor variationContextAccessor)
|
||||
public PublishedValueFallback(ServiceContext serviceContext, IVariationContextAccessor variationContextAccessor, IPublishedValueFallback publishedValueFallback)
|
||||
{
|
||||
_localizationService = serviceContext.LocalizationService;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
_publishedValueFallback = publishedValueFallback;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -182,7 +184,7 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
// if we found a content with the property having a value, return that property value
|
||||
if (property != null && property.HasValue(culture, segment))
|
||||
{
|
||||
value = property.Value<T>(culture, segment);
|
||||
value = property.Value<T>(_publishedValueFallback, culture, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -216,7 +218,7 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
|
||||
if (property.HasValue(culture2, segment))
|
||||
{
|
||||
value = property.Value<T>(culture2, segment);
|
||||
value = property.Value<T>(_publishedValueFallback, culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -250,7 +252,7 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
|
||||
if (content.HasValue(alias, culture2, segment))
|
||||
{
|
||||
value = content.Value<T>(alias, culture2, segment);
|
||||
value = content.Value<T>(_publishedValueFallback, alias, culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -287,7 +289,7 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
|
||||
if (content.HasValue(alias, culture2, segment))
|
||||
{
|
||||
value = content.Value<T>(alias, culture2, segment);
|
||||
value = content.Value<T>(_publishedValueFallback, alias, culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Models.Trees
|
||||
|
||||
@@ -24,9 +24,4 @@
|
||||
<_Parameter1>Umbraco.Tests.Benchmarks</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Logging\Viewer" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
internal class ImageProcessorImageUrlGenerator : IImageUrlGenerator
|
||||
public class ImageProcessorImageUrlGenerator : IImageUrlGenerator
|
||||
{
|
||||
public string GetImageUrl(ImageUrlGenerationOptions options)
|
||||
{
|
||||
@@ -20,6 +20,7 @@ using Umbraco.Core.Serialization;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Web.Models.PublishedContent;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using IntegerValidator = Umbraco.Core.PropertyEditors.Validators.IntegerValidator;
|
||||
|
||||
@@ -141,6 +142,8 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
// register the published snapshot accessor - the "current" published snapshot is in the umbraco context
|
||||
composition.RegisterUnique<IPublishedSnapshotAccessor, UmbracoContextPublishedSnapshotAccessor>();
|
||||
|
||||
composition.RegisterUnique<IVariationContextAccessor, HybridVariationContextAccessor>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="System.Web.Mvc" />
|
||||
<add namespace="System.Web.Mvc.Ajax" />
|
||||
<add namespace="System.Web.Mvc.Html" />
|
||||
<add namespace="System.Web.Routing" />
|
||||
<add namespace="Umbraco.Web" />
|
||||
<add namespace="Umbraco.Core" />
|
||||
<add namespace="Umbraco.Core.Models" />
|
||||
<add namespace="Umbraco.Core.Models.PublishedContent" />
|
||||
<add namespace="Umbraco.Web.Mvc" />
|
||||
<add namespace="Examine" />
|
||||
<add namespace="Umbraco.Web.PublishedModels" />
|
||||
</namespaces>
|
||||
</pages>
|
||||
</system.web.webPages.razor>
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="BlockViewHandler"/>
|
||||
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
|
||||
<system.web>
|
||||
<compilation targetFramework="4.7.2">
|
||||
<assemblies>
|
||||
<add assembly="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
|
||||
<!--
|
||||
Views are compiled by the Microsoft.CodeDom.Providers.DotNetCompilerPlatform which uses the Roslyn compiler
|
||||
from ~/bin/roslyn to expose an ICodeProvider implementation to System.CodeDom.
|
||||
|
||||
For instance, starting with package 1.4.0 (which contains version 1.2.2.0) System.Collections.Immutable
|
||||
lists netstandard2.0 as a supported target, whereas package 1.3.1 only listed net45. So now, when
|
||||
installing, NuGet picks the netstandard2.0 version, thus introducing a dependency to netstandard2.0.
|
||||
|
||||
Somehow, transitive dependencies are not working correctly, and either (a) NuGet fails to properly
|
||||
register this dependency, or (b) when reference assemblies are gathered before compiling views, this
|
||||
dependency is missed. In any case, the result is that the ICodeProvider is passed a list of referenced
|
||||
assemblies that is missing .NET Standard.
|
||||
|
||||
It may be a mix of both. NuGet registers the dependency well enough, that we can actually build the
|
||||
whole application - but it is not doing something that is required in order to have .NET Standard
|
||||
being a dependency when building views.
|
||||
|
||||
See also: https://stackoverflow.com/questions/50165910
|
||||
|
||||
Funny enough, the CSharpCompiler already explicitly adds System.Runtime as a referenced assembly,
|
||||
with a comment mentioning an issue. But it's not adding .NET Standard. So, for the time being, to be sure,
|
||||
we are adding both here.
|
||||
-->
|
||||
<add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<add assembly="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
|
||||
</assemblies>
|
||||
</compilation>
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -48,7 +48,7 @@
|
||||
redirectUrl = Url.Action("AuthorizeUpgrade", "BackOffice")
|
||||
});
|
||||
}
|
||||
@Html.BareMinimumServerVariablesScript(Url, externalLoginUrl, Model.Features, Model.GlobalSettings, Model.UmbracoVersion, Model.UmbracoSettingsSection, Model.IOHelper, Model.TreeCollection)
|
||||
@Html.BareMinimumServerVariablesScript(Url, externalLoginUrl, Model.Features, Model.GlobalSettings, Model.UmbracoVersion, Model.UmbracoSettingsSection, Model.IOHelper, Model.TreeCollection, Model.HttpContextAccessor, Model.HostingEnvironment)
|
||||
|
||||
<script type="text/javascript">
|
||||
document.angularReady = function (app) {
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
on-login="hideLoginScreen()">
|
||||
</umb-login>
|
||||
|
||||
@Html.BareMinimumServerVariablesScript(Url, Url.Action("ExternalLogin", "BackOffice", new { area = ViewData.GetUmbracoPath() }), Model.Features, Model.GlobalSettings, Model.UmbracoVersion, Model.UmbracoSettingsSection, Model.IOHelper, Model.TreeCollection)
|
||||
@Html.BareMinimumServerVariablesScript(Url, Url.Action("ExternalLogin", "BackOffice", new { area = ViewData.GetUmbracoPath() }), Model.Features, Model.GlobalSettings, Model.UmbracoVersion, Model.UmbracoSettingsSection, Model.IOHelper, Model.TreeCollection, Model.HttpContextAccessor, Model.HostingEnvironment)
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc.Html;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Hosting;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -16,6 +17,7 @@ namespace Umbraco.Web
|
||||
/// Outputs and caches a partial view in MVC
|
||||
/// </summary>
|
||||
/// <param name="appCaches"></param>
|
||||
/// <param name="hostingEnvironment"></param>
|
||||
/// <param name="htmlHelper"></param>
|
||||
/// <param name="partialViewName"></param>
|
||||
/// <param name="model"></param>
|
||||
@@ -25,6 +27,7 @@ namespace Umbraco.Web
|
||||
/// <returns></returns>
|
||||
public static IHtmlString CachedPartialView(
|
||||
this AppCaches appCaches,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
HtmlHelper htmlHelper,
|
||||
string partialViewName,
|
||||
object model,
|
||||
@@ -33,7 +36,7 @@ namespace Umbraco.Web
|
||||
ViewDataDictionary viewData = null)
|
||||
{
|
||||
//disable cached partials in debug mode: http://issues.umbraco.org/issue/U4-5940
|
||||
if (htmlHelper.ViewContext.HttpContext.IsDebuggingEnabled)
|
||||
if (hostingEnvironment.IsDebugMode)
|
||||
{
|
||||
// just return a normal partial view instead
|
||||
return htmlHelper.Partial(partialViewName, model, viewData);
|
||||
|
||||
@@ -27,6 +27,7 @@ using Constants = Umbraco.Core.Constants;
|
||||
using JArray = Newtonsoft.Json.Linq.JArray;
|
||||
using Umbraco.Core.Configuration.Grid;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Web.Trees;
|
||||
|
||||
@@ -50,6 +51,8 @@ namespace Umbraco.Web.Editors
|
||||
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly TreeCollection _treeCollection;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public BackOfficeController(
|
||||
IManifestParser manifestParser,
|
||||
@@ -65,7 +68,9 @@ namespace Umbraco.Web.Editors
|
||||
IGridConfig gridConfig,
|
||||
IUmbracoSettingsSection umbracoSettingsSection,
|
||||
IIOHelper ioHelper,
|
||||
TreeCollection treeCollection)
|
||||
TreeCollection treeCollection,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
: base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger, umbracoHelper)
|
||||
{
|
||||
_manifestParser = manifestParser;
|
||||
@@ -76,6 +81,8 @@ namespace Umbraco.Web.Editors
|
||||
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
|
||||
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
|
||||
_treeCollection = treeCollection ?? throw new ArgumentNullException(nameof(treeCollection));
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
protected BackOfficeSignInManager SignInManager => _signInManager ?? (_signInManager = OwinContext.GetBackOfficeSignInManager());
|
||||
@@ -91,8 +98,8 @@ namespace Umbraco.Web.Editors
|
||||
public async Task<ActionResult> Default()
|
||||
{
|
||||
return await RenderDefaultOrProcessExternalLoginAsync(
|
||||
() => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection,_ioHelper, _treeCollection)),
|
||||
() => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection, _ioHelper, _treeCollection)));
|
||||
() => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection,_ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment)),
|
||||
() => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment)));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -175,7 +182,7 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
return await RenderDefaultOrProcessExternalLoginAsync(
|
||||
//The default view to render when there is no external login info or errors
|
||||
() => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection, _ioHelper, _treeCollection)),
|
||||
() => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment)),
|
||||
//The ActionResult to perform if external login is successful
|
||||
() => Redirect("/"));
|
||||
}
|
||||
@@ -255,7 +262,7 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
//cache the result if debugging is disabled
|
||||
var result = HttpContext.IsDebuggingEnabled
|
||||
var result = _hostingEnvironment.IsDebugMode
|
||||
? GetAssetList()
|
||||
: AppCaches.RuntimeCache.GetCacheItem<JArray>(
|
||||
"Umbraco.Web.Editors.BackOfficeController.GetManifestAssetList",
|
||||
@@ -282,10 +289,10 @@ namespace Umbraco.Web.Editors
|
||||
[MinifyJavaScriptResult(Order = 1)]
|
||||
public JavaScriptResult ServerVariables()
|
||||
{
|
||||
var serverVars = new BackOfficeServerVariables(Url, _runtimeState, _features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection, _ioHelper, _treeCollection);
|
||||
var serverVars = new BackOfficeServerVariables(Url, _runtimeState, _features, GlobalSettings, _umbracoVersion, _umbracoSettingsSection, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment);
|
||||
|
||||
//cache the result if debugging is disabled
|
||||
var result = HttpContext.IsDebuggingEnabled
|
||||
var result = _hostingEnvironment.IsDebugMode
|
||||
? ServerVariablesParser.Parse(serverVars.GetServerVariables())
|
||||
: AppCaches.RuntimeCache.GetCacheItem<string>(
|
||||
typeof(BackOfficeController) + "ServerVariables",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Web.Features;
|
||||
using Umbraco.Web.Trees;
|
||||
@@ -9,7 +10,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
public class BackOfficeModel
|
||||
{
|
||||
public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection)
|
||||
public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection, IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
Features = features;
|
||||
GlobalSettings = globalSettings;
|
||||
@@ -17,6 +18,8 @@ namespace Umbraco.Web.Editors
|
||||
UmbracoSettingsSection = umbracoSettingsSection;
|
||||
IOHelper = ioHelper;
|
||||
TreeCollection = treeCollection;
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
HostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
public UmbracoFeatures Features { get; }
|
||||
@@ -25,5 +28,7 @@ namespace Umbraco.Web.Editors
|
||||
public IUmbracoSettingsSection UmbracoSettingsSection { get; }
|
||||
public IIOHelper IOHelper { get; }
|
||||
public TreeCollection TreeCollection { get; }
|
||||
public IHttpContextAccessor HttpContextAccessor { get; }
|
||||
public IHostingEnvironment HostingEnvironment { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Features;
|
||||
@@ -13,8 +14,8 @@ namespace Umbraco.Web.Editors
|
||||
private readonly UmbracoFeatures _features;
|
||||
public IEnumerable<ILanguage> Languages { get; }
|
||||
|
||||
public BackOfficePreviewModel(UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IEnumerable<ILanguage> languages, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection)
|
||||
: base(features, globalSettings, umbracoVersion, umbracoSettingsSection, ioHelper, treeCollection)
|
||||
public BackOfficePreviewModel(UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IEnumerable<ILanguage> languages, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection, IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnvironment)
|
||||
: base(features, globalSettings, umbracoVersion, umbracoSettingsSection, ioHelper, treeCollection, httpContextAccessor, hostingEnvironment)
|
||||
{
|
||||
_features = features;
|
||||
Languages = languages;
|
||||
|
||||
@@ -21,6 +21,7 @@ using Umbraco.Web.PropertyEditors;
|
||||
using Umbraco.Web.Trees;
|
||||
using Constants = Umbraco.Core.Constants;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
@@ -34,25 +35,25 @@ namespace Umbraco.Web.Editors
|
||||
private readonly IRuntimeState _runtimeState;
|
||||
private readonly UmbracoFeatures _features;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly HttpContextBase _httpContext;
|
||||
private readonly IOwinContext _owinContext;
|
||||
private readonly IUmbracoVersion _umbracoVersion;
|
||||
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly TreeCollection _treeCollection;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
internal BackOfficeServerVariables(UrlHelper urlHelper, IRuntimeState runtimeState, UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection)
|
||||
internal BackOfficeServerVariables(UrlHelper urlHelper, IRuntimeState runtimeState, UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection, IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_urlHelper = urlHelper;
|
||||
_runtimeState = runtimeState;
|
||||
_features = features;
|
||||
_globalSettings = globalSettings;
|
||||
_httpContext = _urlHelper.RequestContext.HttpContext;
|
||||
_owinContext = _httpContext.GetOwinContext();
|
||||
_umbracoVersion = umbracoVersion;
|
||||
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
|
||||
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
|
||||
_treeCollection = treeCollection ?? throw new ArgumentNullException(nameof(treeCollection));
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -368,7 +369,7 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
},
|
||||
{
|
||||
"isDebuggingEnabled", _httpContext.IsDebuggingEnabled
|
||||
"isDebuggingEnabled", _hostingEnvironment.IsDebugMode
|
||||
},
|
||||
{
|
||||
"application", GetApplicationState()
|
||||
@@ -377,7 +378,7 @@ namespace Umbraco.Web.Editors
|
||||
"externalLogins", new Dictionary<string, object>
|
||||
{
|
||||
{
|
||||
"providers", _owinContext.Authentication.GetExternalAuthenticationTypes()
|
||||
"providers", _httpContextAccessor.HttpContext.GetOwinContext().Authentication.GetExternalAuthenticationTypes()
|
||||
.Where(p => p.Properties.ContainsKey("UmbracoBackOffice"))
|
||||
.Select(p => new
|
||||
{
|
||||
@@ -464,7 +465,7 @@ namespace Umbraco.Web.Editors
|
||||
app.Add("cacheBuster", $"{version}.{_runtimeState.Level}.{ClientDependencySettings.Instance.Version}".GenerateHash());
|
||||
|
||||
//useful for dealing with virtual paths on the client side when hosted in virtual directories especially
|
||||
app.Add("applicationPath", _httpContext.Request.ApplicationPath.EnsureEndsWith('/'));
|
||||
app.Add("applicationPath", _httpContextAccessor.HttpContext.Request.ApplicationPath.EnsureEndsWith('/'));
|
||||
|
||||
//add the server's GMT time offset in minutes
|
||||
app.Add("serverTimeOffset", Convert.ToInt32(DateTimeOffset.Now.Offset.TotalMinutes));
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Web.UI;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
@@ -31,6 +32,8 @@ namespace Umbraco.Web.Editors
|
||||
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly TreeCollection _treeCollection;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
public PreviewController(
|
||||
UmbracoFeatures features,
|
||||
@@ -41,7 +44,9 @@ namespace Umbraco.Web.Editors
|
||||
IUmbracoVersion umbracoVersion,
|
||||
IUmbracoSettingsSection umbracoSettingsSection,
|
||||
IIOHelper ioHelper,
|
||||
TreeCollection treeCollection)
|
||||
TreeCollection treeCollection,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_features = features;
|
||||
_globalSettings = globalSettings;
|
||||
@@ -52,6 +57,8 @@ namespace Umbraco.Web.Editors
|
||||
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
|
||||
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
|
||||
_treeCollection = treeCollection;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
[UmbracoAuthorize(redirectToUmbracoLogin: true)]
|
||||
@@ -60,7 +67,7 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
var availableLanguages = _localizationService.GetAllLanguages();
|
||||
|
||||
var model = new BackOfficePreviewModel(_features, _globalSettings, _umbracoVersion, availableLanguages, _umbracoSettingsSection, _ioHelper, _treeCollection);
|
||||
var model = new BackOfficePreviewModel(_features, _globalSettings, _umbracoVersion, availableLanguages, _umbracoSettingsSection, _ioHelper, _treeCollection, _httpContextAccessor, _hostingEnvironment);
|
||||
|
||||
if (model.PreviewExtendedHeaderView.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Microsoft.Owin.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
@@ -39,9 +40,9 @@ namespace Umbraco.Web
|
||||
/// These are the bare minimal server variables that are required for the application to start without being authenticated,
|
||||
/// we will load the rest of the server vars after the user is authenticated.
|
||||
/// </remarks>
|
||||
public static IHtmlString BareMinimumServerVariablesScript(this HtmlHelper html, UrlHelper uri, string externalLoginsUrl, UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection)
|
||||
public static IHtmlString BareMinimumServerVariablesScript(this HtmlHelper html, UrlHelper uri, string externalLoginsUrl, UmbracoFeatures features, IGlobalSettings globalSettings, IUmbracoVersion umbracoVersion, IUmbracoSettingsSection umbracoSettingsSection, IIOHelper ioHelper, TreeCollection treeCollection, IHttpContextAccessor httpContextAccessor, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
var serverVars = new BackOfficeServerVariables(uri, Current.RuntimeState, features, globalSettings, umbracoVersion, umbracoSettingsSection, ioHelper, treeCollection);
|
||||
var serverVars = new BackOfficeServerVariables(uri, Current.RuntimeState, features, globalSettings, umbracoVersion, umbracoSettingsSection, ioHelper, treeCollection, httpContextAccessor, hostingEnvironment);
|
||||
var minVars = serverVars.BareMinimumServerVariables();
|
||||
|
||||
var str = @"<script type=""text/javascript"">
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace Umbraco.Web
|
||||
var contextualKey = contextualKeyBuilder(model, viewData);
|
||||
cacheKey.AppendFormat("c{0}-", contextualKey);
|
||||
}
|
||||
return Current.AppCaches.CachedPartialView(htmlHelper, partialViewName, model, cachedSeconds, cacheKey.ToString(), viewData);
|
||||
return Current.AppCaches.CachedPartialView(Current.HostingEnvironment, htmlHelper, partialViewName, model, cachedSeconds, cacheKey.ToString(), viewData);
|
||||
}
|
||||
|
||||
public static MvcHtmlString EditorFor<T>(this HtmlHelper htmlHelper, string templateName = "", string htmlFieldName = "", object additionalViewData = null)
|
||||
|
||||
@@ -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,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 />
|
||||
|
||||
@@ -29,26 +29,24 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
[InstallSetupStep(InstallationType.NewInstall, "User", 20, "")]
|
||||
internal class NewInstallStep : InstallSetupStep<UserModel>
|
||||
{
|
||||
private readonly HttpContextBase _http;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IUserService _userService;
|
||||
private readonly DatabaseBuilder _databaseBuilder;
|
||||
private static HttpClient _httpClient;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IUserPasswordConfiguration _passwordConfiguration;
|
||||
private readonly BackOfficeUserManager<BackOfficeIdentityUser> _userManager;
|
||||
private readonly IUmbracoSettingsSection _umbracoSettingsSection;
|
||||
private readonly IConnectionStrings _connectionStrings;
|
||||
|
||||
public NewInstallStep(HttpContextBase http, IUserService userService, DatabaseBuilder databaseBuilder, IGlobalSettings globalSettings, IUserPasswordConfiguration passwordConfiguration, IUmbracoSettingsSection umbracoSettingsSection, IConnectionStrings connectionStrings)
|
||||
public NewInstallStep(IHttpContextAccessor httpContextAccessor, IUserService userService, DatabaseBuilder databaseBuilder, IGlobalSettings globalSettings, IUserPasswordConfiguration passwordConfiguration, IUmbracoSettingsSection umbracoSettingsSection, IConnectionStrings connectionStrings)
|
||||
{
|
||||
_http = http;
|
||||
_userService = userService;
|
||||
_databaseBuilder = databaseBuilder;
|
||||
_globalSettings = globalSettings;
|
||||
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
|
||||
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
|
||||
_databaseBuilder = databaseBuilder ?? throw new ArgumentNullException(nameof(databaseBuilder));
|
||||
_globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings));
|
||||
_passwordConfiguration = passwordConfiguration ?? throw new ArgumentNullException(nameof(passwordConfiguration));
|
||||
_umbracoSettingsSection = umbracoSettingsSection ?? throw new ArgumentNullException(nameof(umbracoSettingsSection));
|
||||
_connectionStrings = connectionStrings ?? throw new ArgumentNullException(nameof(connectionStrings));
|
||||
_userManager = _http.GetOwinContext().GetBackOfficeUserManager();
|
||||
}
|
||||
|
||||
public override async Task<InstallSetupResult> ExecuteAsync(UserModel user)
|
||||
@@ -59,15 +57,16 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
throw new InvalidOperationException("Could not find the super user!");
|
||||
}
|
||||
|
||||
var membershipUser = await _userManager.FindByIdAsync(Constants.Security.SuperUserId);
|
||||
var userManager = _httpContextAccessor.HttpContext.GetOwinContext().GetBackOfficeUserManager();
|
||||
var membershipUser = await userManager.FindByIdAsync(Constants.Security.SuperUserId);
|
||||
if (membershipUser == null)
|
||||
{
|
||||
throw new InvalidOperationException($"No user found in membership provider with id of {Constants.Security.SuperUserId}.");
|
||||
}
|
||||
|
||||
//To change the password here we actually need to reset it since we don't have an old one to use to change
|
||||
var resetToken = await _userManager.GeneratePasswordResetTokenAsync(membershipUser.Id);
|
||||
var resetResult = await _userManager.ChangePasswordWithResetAsync(membershipUser.Id, resetToken, user.Password.Trim());
|
||||
var resetToken = await userManager.GeneratePasswordResetTokenAsync(membershipUser.Id);
|
||||
var resetResult = await userManager.ChangePasswordWithResetAsync(membershipUser.Id, resetToken, user.Password.Trim());
|
||||
if (!resetResult.Succeeded)
|
||||
{
|
||||
throw new InvalidOperationException("Could not reset password: " + string.Join(", ", resetResult.Errors));
|
||||
@@ -138,7 +137,7 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
|
||||
// In this one case when it's a brand new install and nothing has been configured, make sure the
|
||||
// back office cookie is cleared so there's no old cookies lying around causing problems
|
||||
_http.ExpireCookie(_umbracoSettingsSection.Security.AuthCookieName);
|
||||
_httpContextAccessor.HttpContext.ExpireCookie(_umbracoSettingsSection.Security.AuthCookieName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,16 +18,16 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
PerformsAppRestart = true)]
|
||||
internal class SetUmbracoVersionStep : InstallSetupStep<object>
|
||||
{
|
||||
private readonly HttpContextBase _httpContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly InstallHelper _installHelper;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IUmbracoVersion _umbracoVersion;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
|
||||
public SetUmbracoVersionStep(HttpContextBase httpContext, InstallHelper installHelper, IGlobalSettings globalSettings, IUserService userService, IUmbracoVersion umbracoVersion, IIOHelper ioHelper)
|
||||
public SetUmbracoVersionStep(IHttpContextAccessor httpContextAccessor, InstallHelper installHelper, IGlobalSettings globalSettings, IUserService userService, IUmbracoVersion umbracoVersion, IIOHelper ioHelper)
|
||||
{
|
||||
_httpContext = httpContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_installHelper = installHelper;
|
||||
_globalSettings = globalSettings;
|
||||
_userService = userService;
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
|
||||
public override Task<InstallSetupResult> ExecuteAsync(object model)
|
||||
{
|
||||
var security = new WebSecurity(_httpContext, _userService, _globalSettings, _ioHelper);
|
||||
var security = new WebSecurity(_httpContextAccessor.HttpContext, _userService, _globalSettings, _ioHelper);
|
||||
|
||||
if (security.IsAuthenticated() == false && _globalSettings.ConfigurationStatus.IsNullOrWhiteSpace())
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.Web.UI;
|
||||
using ClientDependency.Core;
|
||||
using ClientDependency.Core.CompositeFiles;
|
||||
using Umbraco.Composing;
|
||||
using Umbraco.Core.Hosting;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
@@ -13,6 +15,18 @@ namespace Umbraco.Web.Mvc
|
||||
/// </remarks>
|
||||
public class MinifyJavaScriptResultAttribute : ActionFilterAttribute
|
||||
{
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
public MinifyJavaScriptResultAttribute()
|
||||
{
|
||||
_hostingEnvironment = Current.HostingEnvironment;
|
||||
}
|
||||
|
||||
public MinifyJavaScriptResultAttribute(IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minify the result if in release mode
|
||||
/// </summary>
|
||||
@@ -24,7 +38,7 @@ namespace Umbraco.Web.Mvc
|
||||
if (filterContext.Result == null) return;
|
||||
var jsResult = filterContext.Result as JavaScriptResult;
|
||||
if (jsResult == null) return;
|
||||
if (filterContext.HttpContext.IsDebuggingEnabled) return;
|
||||
if (_hostingEnvironment.IsDebugMode) return;
|
||||
|
||||
//minify the result
|
||||
var result = jsResult.Script;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco context accessor.
|
||||
/// </summary>
|
||||
public virtual IUmbracoContextAccessor UmbracoContextAccessor { get; set; }
|
||||
public IUmbracoContextAccessor UmbracoContextAccessor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the services context.
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Umbraco.Web.Runtime
|
||||
composition.Register<IFilePermissionHelper, FilePermissionHelper>(Lifetime.Singleton);
|
||||
|
||||
composition.RegisterUnique<IHttpContextAccessor, AspNetHttpContextAccessor>(); // required for hybrid accessors
|
||||
composition.RegisterUnique<ICookieManager, AspNetCookieManager>();
|
||||
composition.RegisterUnique<ICookieManager, AspNetCookieManager>();
|
||||
|
||||
composition.ComposeWebMappingProfiles();
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Web.Runtime
|
||||
|
||||
// register accessors for cultures
|
||||
composition.RegisterUnique<IDefaultCultureAccessor, DefaultCultureAccessor>();
|
||||
composition.RegisterUnique<IVariationContextAccessor, HybridVariationContextAccessor>();
|
||||
|
||||
|
||||
// register the http context and umbraco context accessors
|
||||
// we *should* use the HttpContextUmbracoContextAccessor, however there are cases when
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -173,7 +173,6 @@
|
||||
<Compile Include="Models\Identity\IdentityMapDefinition.cs" />
|
||||
<Compile Include="Models\Identity\IdentityUser.cs" />
|
||||
<Compile Include="Models\Identity\UserLoginInfoWrapper.cs" />
|
||||
<Compile Include="Models\ImageProcessorImageUrlGenerator.cs" />
|
||||
<Compile Include="Models\Mapping\CommonMapper.cs" />
|
||||
<Compile Include="Models\Mapping\ContentMapDefinition.cs" />
|
||||
<Compile Include="Models\Mapping\ContentPropertyBasicMapper.cs" />
|
||||
@@ -190,9 +189,11 @@
|
||||
<Compile Include="Models\Mapping\TabsAndPropertiesMapper.cs" />
|
||||
<Compile Include="Models\Mapping\UserMapDefinition.cs" />
|
||||
<Compile Include="Models\Membership\UmbracoMembershipMember.cs" />
|
||||
<Compile Include="Models\PublishedContent\HybridVariationContextAccessor.cs" />
|
||||
<Compile Include="Models\Trees\MenuItemCollection.cs" />
|
||||
<Compile Include="Models\Trees\MenuItemList.cs" />
|
||||
<Compile Include="Models\Trees\TreeNodeCollection.cs" />
|
||||
<Compile Include="Models\Trees\TreeNodeExtensions.cs" />
|
||||
<Compile Include="Models\Trees\TreeRootNode.cs" />
|
||||
<Compile Include="Mvc\HttpUmbracoFormRouteStringException.cs" />
|
||||
<Compile Include="Mvc\ModelBindingExceptionFilter.cs" />
|
||||
<Compile Include="Mvc\StatusCodeFilterAttribute.cs" />
|
||||
@@ -308,10 +309,8 @@
|
||||
<Compile Include="Features\DisabledFeatures.cs" />
|
||||
<Compile Include="Features\EnabledFeatures.cs" />
|
||||
<Compile Include="Features\UmbracoFeatures.cs" />
|
||||
<Compile Include="HybridAccessorBase.cs" />
|
||||
<Compile Include="HybridUmbracoContextAccessor.cs" />
|
||||
<Compile Include="HttpContextUmbracoContextAccessor.cs" />
|
||||
<Compile Include="HybridEventMessagesAccessor.cs" />
|
||||
<Compile Include="IHttpContextAccessor.cs" />
|
||||
<Compile Include="Composing\CompositionExtensions\WebMappingProfiles.cs" />
|
||||
<Compile Include="Editors\BackOfficeNotificationsController.cs" />
|
||||
@@ -329,10 +328,6 @@
|
||||
<Compile Include="Editors\IEditorValidator.cs" />
|
||||
<Compile Include="Editors\EditorModelEventManager.cs" />
|
||||
<Compile Include="HtmlHelperBackOfficeExtensions.cs" />
|
||||
<Compile Include="Models\ContentTypeImportModel.cs" />
|
||||
<Compile Include="Models\PublishedContent\HttpContextVariationContextAccessor.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedValueFallback.cs" />
|
||||
<Compile Include="Models\Trees\ExportMember.cs" />
|
||||
<Compile Include="Composing\ModuleInjector.cs" />
|
||||
<Compile Include="Mvc\FilteredControllerFactoryCollection.cs" />
|
||||
<Compile Include="Mvc\FilteredControllerFactoryCollectionBuilder.cs" />
|
||||
@@ -381,7 +376,6 @@
|
||||
<Compile Include="Editors\PublishedSnapshotCacheStatusController.cs" />
|
||||
<Compile Include="Trees\TreeAttribute.cs" />
|
||||
<Compile Include="Routing\NotFoundHandlerHelper.cs" />
|
||||
<Compile Include="Models\LocalPackageInstallModel.cs" />
|
||||
<Compile Include="Mvc\ControllerContextExtensions.cs" />
|
||||
<Compile Include="Mvc\DisableBrowserCacheAttribute.cs" />
|
||||
<Compile Include="Mvc\EnsurePartialViewMacroViewContextFilterAttribute.cs" />
|
||||
@@ -496,7 +490,6 @@
|
||||
<Compile Include="Trees\LanguageTreeController.cs" />
|
||||
<Compile Include="Trees\MemberTreeController.cs" />
|
||||
<Compile Include="Trees\MenuRenderingEventArgs.cs" />
|
||||
<Compile Include="Models\Trees\CreateChildEntity.cs" />
|
||||
<Compile Include="Trees\TemplatesTreeController.cs" />
|
||||
<Compile Include="Trees\TreeControllerBase.cs" />
|
||||
<Compile Include="JavaScript\AssetInitialization.cs" />
|
||||
@@ -538,10 +531,7 @@
|
||||
<Compile Include="FormDataCollectionExtensions.cs" />
|
||||
<Compile Include="Trees\MediaTreeController.cs" />
|
||||
<Compile Include="Trees\ContentTreeControllerBase.cs" />
|
||||
<Compile Include="Models\Trees\TreeRootNode.cs" />
|
||||
<Compile Include="Trees\TreeController.cs" />
|
||||
<Compile Include="Models\Trees\TreeNodeCollection.cs" />
|
||||
<Compile Include="Models\Trees\TreeNodeExtensions.cs" />
|
||||
<Compile Include="Trees\TreeNodeRenderingEventArgs.cs" />
|
||||
<Compile Include="Trees\TreeNodesRenderingEventArgs.cs" />
|
||||
<Compile Include="Trees\TreeQueryStringParameters.cs" />
|
||||
|
||||
@@ -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