diff --git a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs
index cd15335e57..b541182de0 100644
--- a/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs
+++ b/src/Umbraco.Tests/Scheduling/BackgroundTaskRunnerTests.cs
@@ -749,7 +749,7 @@ namespace Umbraco.Tests.Scheduling
HasRun = true;
}
- public override Task PerformRunAsync()
+ public override Task PerformRunAsync(CancellationToken token)
{
throw new NotImplementedException();
}
@@ -833,7 +833,7 @@ namespace Umbraco.Tests.Scheduling
Thread.Sleep(_runMilliseconds);
}
- public override Task PerformRunAsync()
+ public override Task PerformRunAsync(CancellationToken token)
{
throw new NotImplementedException();
}
diff --git a/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs b/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs
index cbd2e0e519..dc8aa15f6a 100644
--- a/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs
+++ b/src/Umbraco.Web/Mvc/AdminTokenAuthorizeAttribute.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
@@ -36,22 +37,33 @@ namespace Umbraco.Web.Mvc
return _applicationContext ?? ApplicationContext.Current;
}
+ public const string AuthorizationType = "AToken";
+
///
- /// Used to return the value that needs to go in the Authorization header
+ /// Used to return the full value that needs to go in the Authorization header
///
///
///
public static string GetAuthHeaderTokenVal(ApplicationContext appContext)
{
- var admin = appContext.Services.UserService.GetUserById(0);
+ return string.Format("{0} {1}", AuthorizationType, GetAuthHeaderVal(appContext));
+ }
+ public static AuthenticationHeaderValue GetAuthenticationHeaderValue(ApplicationContext appContext)
+ {
+ return new AuthenticationHeaderValue(AuthorizationType, GetAuthHeaderVal(appContext));
+ }
+
+ private static string GetAuthHeaderVal(ApplicationContext appContext)
+ {
+ var admin = appContext.Services.UserService.GetUserById(0);
var token = string.Format("{0}u____u{1}u____u{2}", admin.Email, admin.Username, admin.RawPasswordValue);
var encrypted = token.EncryptWithMachineKey();
var bytes = Encoding.UTF8.GetBytes(encrypted);
var base64 = Convert.ToBase64String(bytes);
- return "AToken val=\"" + base64 + "\"";
+ return string.Format("val=\"{0}\"", base64);
}
///
diff --git a/src/Umbraco.Web/Scheduling/LogScrubber.cs b/src/Umbraco.Web/Scheduling/LogScrubber.cs
index d6c096bf74..14f534653d 100644
--- a/src/Umbraco.Web/Scheduling/LogScrubber.cs
+++ b/src/Umbraco.Web/Scheduling/LogScrubber.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Caching;
@@ -74,7 +75,7 @@ namespace Umbraco.Web.Scheduling
}
}
- public override Task PerformRunAsync()
+ public override Task PerformRunAsync(CancellationToken token)
{
throw new NotImplementedException();
}
diff --git a/src/Umbraco.Web/Scheduling/RecurringTaskBase.cs b/src/Umbraco.Web/Scheduling/RecurringTaskBase.cs
index d710a70e03..dc82795852 100644
--- a/src/Umbraco.Web/Scheduling/RecurringTaskBase.cs
+++ b/src/Umbraco.Web/Scheduling/RecurringTaskBase.cs
@@ -55,7 +55,7 @@ namespace Umbraco.Web.Scheduling
/// Classes inheriting from RecurringTaskBase must implement PerformRun.
public virtual async Task RunAsync(CancellationToken token)
{
- await PerformRunAsync();
+ await PerformRunAsync(token);
Repeat();
}
@@ -95,8 +95,9 @@ namespace Umbraco.Web.Scheduling
///
/// Runs the task asynchronously.
///
+ /// A cancellation token.
/// A instance representing the execution of the background task.
- public abstract Task PerformRunAsync();
+ public abstract Task PerformRunAsync(CancellationToken token);
///
/// Gets a new occurence of the recurring task.
diff --git a/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs b/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs
index 9db21fba8a..0f7cb8c205 100644
--- a/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs
+++ b/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs
@@ -1,12 +1,10 @@
using System;
-using System.Diagnostics;
-using System.Net;
-using System.Text;
+using System.Net.Http;
+using System.Threading;
using System.Threading.Tasks;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
-using Umbraco.Core.Publishing;
using Umbraco.Core.Sync;
using Umbraco.Web.Mvc;
@@ -41,6 +39,12 @@ namespace Umbraco.Web.Scheduling
public override void PerformRun()
{
+ throw new NotImplementedException();
+ }
+
+ public override async Task PerformRunAsync(CancellationToken token)
+ {
+
if (_appContext == null) return;
if (ServerEnvironmentHelper.GetStatus(_settings) == CurrentServerEnvironmentStatus.Slave)
{
@@ -57,7 +61,7 @@ namespace Umbraco.Web.Scheduling
var umbracoBaseUrl = ServerEnvironmentHelper.GetCurrentServerUmbracoBaseUrl(_appContext, _settings);
try
- {
+ {
if (string.IsNullOrWhiteSpace(umbracoBaseUrl))
{
@@ -66,13 +70,26 @@ namespace Umbraco.Web.Scheduling
else
{
var url = string.Format("{0}RestServices/ScheduledPublish/Index", umbracoBaseUrl.EnsureEndsWith('/'));
- using (var wc = new WebClient())
+ using (var wc = new HttpClient())
{
+ var request = new HttpRequestMessage()
+ {
+ RequestUri = new Uri(url),
+ Method = HttpMethod.Post,
+ Content = new StringContent(string.Empty)
+ };
//pass custom the authorization header
- wc.Headers.Set("Authorization", AdminTokenAuthorizeAttribute.GetAuthHeaderTokenVal(_appContext));
+ request.Headers.Authorization = AdminTokenAuthorizeAttribute.GetAuthenticationHeaderValue(_appContext);
- var result = wc.UploadString(url, "");
- }
+ try
+ {
+ var result = await wc.SendAsync(request, token);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error("An error occurred calling scheduled publish url", ex);
+ }
+ }
}
}
catch (Exception ee)
@@ -88,14 +105,9 @@ namespace Umbraco.Web.Scheduling
}
}
- public override Task PerformRunAsync()
- {
- throw new NotImplementedException();
- }
-
public override bool IsAsync
{
- get { return false; }
+ get { return true; }
}
public override bool RunsOnShutdown
diff --git a/src/Umbraco.Web/Scheduling/ScheduledTasks.cs b/src/Umbraco.Web/Scheduling/ScheduledTasks.cs
index cba3cb4fc8..1015b2d4f6 100644
--- a/src/Umbraco.Web/Scheduling/ScheduledTasks.cs
+++ b/src/Umbraco.Web/Scheduling/ScheduledTasks.cs
@@ -1,15 +1,13 @@
using System;
using System.Collections;
-using System.Linq;
using System.Net;
+using System.Net.Http;
+using System.Threading;
using System.Threading.Tasks;
-using System.Xml;
-using Umbraco.Core.Configuration;
+using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
-using Umbraco.Core.Publishing;
using Umbraco.Core.Sync;
-using Umbraco.Core;
namespace Umbraco.Web.Scheduling
{
@@ -44,18 +42,19 @@ namespace Umbraco.Web.Scheduling
return new ScheduledTasks(this);
}
- private void ProcessTasks()
+ private async Task ProcessTasksAsync(CancellationToken token)
{
var scheduledTasks = _settings.ScheduledTasks.Tasks;
foreach (var t in scheduledTasks)
{
var runTask = false;
- if (!ScheduledTaskTimes.ContainsKey(t.Alias))
+ if (ScheduledTaskTimes.ContainsKey(t.Alias) == false)
{
runTask = true;
ScheduledTaskTimes.Add(t.Alias, DateTime.Now);
}
- /// Add 1 second to timespan to compensate for differencies in timer
+
+ // Add 1 second to timespan to compensate for differencies in timer
else if (
new TimeSpan(
DateTime.Now.Ticks - ((DateTime)ScheduledTaskTimes[t.Alias]).Ticks).TotalSeconds + 1 >= t.Interval)
@@ -66,33 +65,46 @@ namespace Umbraco.Web.Scheduling
if (runTask)
{
- bool taskResult = GetTaskByHttp(t.Url);
+ var taskResult = await GetTaskByHttpAync(t.Url, token);
if (t.Log)
LogHelper.Info(string.Format("{0} has been called with response: {1}", t.Alias, taskResult));
}
}
}
- private bool GetTaskByHttp(string url)
+ private async Task GetTaskByHttpAync(string url, CancellationToken token)
{
- var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
-
- try
+ using (var wc = new HttpClient())
{
- using (var response = (HttpWebResponse)myHttpWebRequest.GetResponse())
+ var request = new HttpRequestMessage()
{
- return response.StatusCode == HttpStatusCode.OK;
- }
- }
- catch (Exception ex)
- {
- LogHelper.Error("An error occurred calling web task for url: " + url, ex);
- }
+ RequestUri = new Uri(url),
+ Method = HttpMethod.Get,
+ Content = new StringContent(string.Empty)
+ };
- return false;
+ //TODO: pass custom the authorization header, currently these aren't really secured!
+ //request.Headers.Authorization = AdminTokenAuthorizeAttribute.GetAuthenticationHeaderValue(_appContext);
+
+ try
+ {
+ var result = await wc.SendAsync(request, token);
+ return result.StatusCode == HttpStatusCode.OK;
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error("An error occurred calling web task for url: " + url, ex);
+ }
+ return false;
+ }
}
public override void PerformRun()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override async Task PerformRunAsync(CancellationToken token)
{
if (ServerEnvironmentHelper.GetStatus(_settings) == CurrentServerEnvironmentStatus.Slave)
{
@@ -108,7 +120,7 @@ namespace Umbraco.Web.Scheduling
try
{
- ProcessTasks();
+ await ProcessTasksAsync(token);
}
catch (Exception ee)
{
@@ -121,14 +133,9 @@ namespace Umbraco.Web.Scheduling
}
}
- public override Task PerformRunAsync()
- {
- throw new NotImplementedException();
- }
-
public override bool IsAsync
{
- get { return false; }
+ get { return true; }
}
public override bool RunsOnShutdown
diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs
index e32fdc3a83..cd85e82686 100644
--- a/src/Umbraco.Web/UmbracoModule.cs
+++ b/src/Umbraco.Web/UmbracoModule.cs
@@ -562,21 +562,26 @@ namespace Umbraco.Web
var httpContext = ((HttpApplication)sender).Context;
LogHelper.Debug("Begin request: {0}.", () => httpContext.Request.Url);
BeginRequest(new HttpContextWrapper(httpContext));
-
- //disable asp.net headers (security)
- try
- {
- httpContext.Response.Headers.Remove("Server");
- //this doesn't normally work since IIS sets it but we'll keep it here anyways.
- httpContext.Response.Headers.Remove("X-Powered-By");
- }
- catch (PlatformNotSupportedException ex)
- {
- // can't remove headers this way on IIS6 or cassini.
- }
-
};
+ //disable asp.net headers (security)
+ // This is the correct place to modify headers according to MS:
+ // https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/65241-Heap-error-from-header-manipulation?p=0#comment220889
+ app.PostReleaseRequestState += (sender, args) =>
+ {
+ var httpContext = ((HttpApplication)sender).Context;
+ try
+ {
+ httpContext.Response.Headers.Remove("Server");
+ //this doesn't normally work since IIS sets it but we'll keep it here anyways.
+ httpContext.Response.Headers.Remove("X-Powered-By");
+ }
+ catch (PlatformNotSupportedException ex)
+ {
+ // can't remove headers this way on IIS6 or cassini.
+ }
+ };
+
app.PostResolveRequestCache += (sender, e) =>
{
var httpContext = ((HttpApplication)sender).Context;