2018-06-29 19:52:40 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Web;
|
2019-01-07 10:43:28 +01:00
|
|
|
|
using Umbraco.Core;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using Umbraco.Core.Logging;
|
|
|
|
|
|
using Umbraco.Web.Composing;
|
2018-07-06 18:37:07 +02:00
|
|
|
|
using Umbraco.Web.Routing;
|
2018-07-06 17:36:33 +02:00
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
|
namespace Umbraco.Web
|
2018-06-29 13:17:46 +02:00
|
|
|
|
{
|
2018-07-06 18:37:07 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Represents the main Umbraco module.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// <para>Register that one in web.config.</para>
|
|
|
|
|
|
/// <para>It will inject <see cref="UmbracoInjectedModule"/> which contains most of the actual code.</para>
|
|
|
|
|
|
/// </remarks>
|
|
|
|
|
|
public class UmbracoModule : ModuleInjector<UmbracoInjectedModule>
|
2018-07-06 17:36:33 +02:00
|
|
|
|
{
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// <summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
/// Occurs when...
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// </summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
internal static event EventHandler<RoutableAttemptEventArgs> RouteAttempt;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
/// Occurs when...
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// </summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
public static event EventHandler<UmbracoRequestEventArgs> EndRequest;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
/// Triggers the RouteAttempt event.
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// </summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
internal static void OnRouteAttempt(object sender, RoutableAttemptEventArgs args)
|
2018-06-29 19:52:40 +02:00
|
|
|
|
{
|
2018-07-06 18:37:07 +02:00
|
|
|
|
RouteAttempt?.Invoke(sender, args);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
/// Triggers the EndRequest event.
|
2018-06-29 19:52:40 +02:00
|
|
|
|
/// </summary>
|
2018-07-06 18:37:07 +02:00
|
|
|
|
internal static void OnEndRequest(object sender, UmbracoRequestEventArgs args)
|
2018-06-29 19:52:40 +02:00
|
|
|
|
{
|
2018-07-06 18:37:07 +02:00
|
|
|
|
EndRequest?.Invoke(sender, args);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// returns a value indicating whether redirection took place and the request has
|
|
|
|
|
|
// been completed - because we don't want to Response.End() here to terminate
|
|
|
|
|
|
// everything properly.
|
|
|
|
|
|
internal static bool HandleHttpResponseStatus(HttpContextBase context, PublishedRequest pcr, ILogger logger)
|
|
|
|
|
|
{
|
|
|
|
|
|
var end = false;
|
|
|
|
|
|
var response = context.Response;
|
|
|
|
|
|
|
2018-08-14 22:36:47 +01:00
|
|
|
|
logger.Debug<UmbracoModule>("Response status: Redirect={Redirect}, Is404={Is404}, StatusCode={ResponseStatusCode}",
|
|
|
|
|
|
pcr.IsRedirect ? (pcr.IsRedirectPermanent ? "permanent" : "redirect") : "none",
|
|
|
|
|
|
pcr.Is404 ? "true" : "false",
|
|
|
|
|
|
pcr.ResponseStatusCode);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
|
|
|
|
|
if(pcr.Cacheability != default)
|
|
|
|
|
|
response.Cache.SetCacheability(pcr.Cacheability);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var cacheExtension in pcr.CacheExtensions)
|
|
|
|
|
|
response.Cache.AppendCacheExtension(cacheExtension);
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var header in pcr.Headers)
|
|
|
|
|
|
response.AppendHeader(header.Key, header.Value);
|
|
|
|
|
|
|
|
|
|
|
|
if (pcr.IsRedirect)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pcr.IsRedirectPermanent)
|
|
|
|
|
|
response.RedirectPermanent(pcr.RedirectUrl, false); // do not end response
|
|
|
|
|
|
else
|
|
|
|
|
|
response.Redirect(pcr.RedirectUrl, false); // do not end response
|
|
|
|
|
|
end = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (pcr.Is404)
|
|
|
|
|
|
{
|
|
|
|
|
|
response.StatusCode = 404;
|
2019-01-07 10:43:28 +01:00
|
|
|
|
response.TrySkipIisCustomErrors = Current.Configs.Settings().WebRouting.TrySkipIisCustomErrors;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
|
|
|
|
|
if (response.TrySkipIisCustomErrors == false)
|
|
|
|
|
|
logger.Warn<UmbracoModule>("Status code is 404 yet TrySkipIisCustomErrors is false - IIS will take over.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pcr.ResponseStatusCode > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// set status code -- even for redirects
|
|
|
|
|
|
response.StatusCode = pcr.ResponseStatusCode;
|
|
|
|
|
|
response.StatusDescription = pcr.ResponseStatusDescription;
|
|
|
|
|
|
}
|
|
|
|
|
|
//if (pcr.IsRedirect)
|
|
|
|
|
|
// response.End(); // end response -- kills the thread and does not return!
|
|
|
|
|
|
|
|
|
|
|
|
if (pcr.IsRedirect == false) return end;
|
|
|
|
|
|
|
|
|
|
|
|
response.Flush();
|
|
|
|
|
|
// bypass everything and directly execute EndRequest event -- but returns
|
|
|
|
|
|
context.ApplicationInstance.CompleteRequest();
|
|
|
|
|
|
// though some say that .CompleteRequest() does not properly shutdown the response
|
|
|
|
|
|
// and the request will hang until the whole code has run... would need to test?
|
|
|
|
|
|
logger.Debug<UmbracoModule>("Response status: redirecting, complete request now.");
|
|
|
|
|
|
|
|
|
|
|
|
return end;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|