PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/Web/HttpModules/WwwSubDomainModule.cs

#
C# | 151 lines | 79 code | 22 blank | 50 comment | 14 complexity | 7588da0abdc0891250dc29d116aade21 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. namespace BlogEngine.Core.Web.HttpModules
  2. {
  3. using System;
  4. using System.Text.RegularExpressions;
  5. using System.Web;
  6. /// <summary>
  7. /// Removes or adds the www subdomain from all requests
  8. /// and makes a permanent redirection to the new location.
  9. /// </summary>
  10. public class WwwSubDomainModule : IHttpModule
  11. {
  12. #region Constants and Fields
  13. /// <summary>
  14. /// The link regex.
  15. /// </summary>
  16. private static readonly Regex LinkRegex = new Regex(
  17. "(http|https)://www\\.", RegexOptions.IgnoreCase | RegexOptions.Compiled);
  18. #endregion
  19. #region Implemented Interfaces
  20. #region IHttpModule
  21. /// <summary>
  22. /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
  23. /// </summary>
  24. public void Dispose()
  25. {
  26. // Nothing to dispose
  27. }
  28. /// <summary>
  29. /// Initializes a module and prepares it to handle requests.
  30. /// </summary>
  31. /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
  32. public void Init(HttpApplication context)
  33. {
  34. context.BeginRequest += ContextBeginRequest;
  35. }
  36. #endregion
  37. #endregion
  38. #region Methods
  39. /// <summary>
  40. /// Adds the www subdomain to the request and redirects.
  41. /// </summary>
  42. /// <param name="context">
  43. /// The context.
  44. /// </param>
  45. private static void AddWww(HttpContext context)
  46. {
  47. var url = context.Request.Url.ToString().Replace("://", "://www.");
  48. PermanentRedirect(url, context);
  49. }
  50. /// <summary>
  51. /// Sends permanent redirection headers (301)
  52. /// </summary>
  53. /// <param name="url">
  54. /// The url to redirect to.
  55. /// </param>
  56. /// <param name="context">
  57. /// The HTTP context.
  58. /// </param>
  59. private static void PermanentRedirect(string url, HttpContext context)
  60. {
  61. if (url.EndsWith("default.aspx", StringComparison.OrdinalIgnoreCase))
  62. {
  63. url = url.ToLowerInvariant().Replace("default.aspx", string.Empty);
  64. }
  65. context.Response.Clear();
  66. context.Response.StatusCode = 301;
  67. context.Response.AppendHeader("location", url);
  68. context.Response.End();
  69. }
  70. /// <summary>
  71. /// Removes the www subdomain from the request and redirects.
  72. /// </summary>
  73. /// <param name="context">
  74. /// The context.
  75. /// </param>
  76. private static void RemoveWww(HttpContext context)
  77. {
  78. var url = context.Request.Url.ToString();
  79. if (!LinkRegex.IsMatch(url))
  80. {
  81. return;
  82. }
  83. url = LinkRegex.Replace(url, "$1://");
  84. PermanentRedirect(url, context);
  85. }
  86. /// <summary>
  87. /// Handles the BeginRequest event of the context control.
  88. /// </summary>
  89. /// <param name="sender">The source of the event.</param>
  90. /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
  91. private static void ContextBeginRequest(object sender, EventArgs e)
  92. {
  93. // Clear the InstanceIdOverride to ensure any values are not
  94. // carried over from previous times this thread from the thread
  95. // pool was used.
  96. //
  97. // This should be done at the beginning of each HTTP request as
  98. // early as possible. It is being done here because in the
  99. // list of HTTP modules defined in the web.config file, this
  100. // module (WwwSubdomainModule) is the first defined one so will
  101. // fire before any other modules.
  102. Blog.InstanceIdOverride = Guid.Empty;
  103. if (BlogSettings.Instance.HandleWwwSubdomain == "ignore" ||
  104. string.IsNullOrEmpty(BlogSettings.Instance.HandleWwwSubdomain))
  105. {
  106. return;
  107. }
  108. var context = ((HttpApplication)sender).Context;
  109. if (context.Request.HttpMethod != "GET" || context.Request.RawUrl.Contains("/admin/") ||
  110. context.Request.IsLocal)
  111. {
  112. return;
  113. }
  114. if (context.Request.PhysicalPath.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))
  115. {
  116. var url = context.Request.Url.ToString();
  117. if (url.Contains("://www.") && BlogSettings.Instance.HandleWwwSubdomain == "remove")
  118. {
  119. RemoveWww(context);
  120. }
  121. if (!url.Contains("://www.") && BlogSettings.Instance.HandleWwwSubdomain == "add")
  122. {
  123. AddWww(context);
  124. }
  125. }
  126. }
  127. #endregion
  128. }
  129. }