RewriterModule.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System;
  2. using System.Text.RegularExpressions;
  3. using System.Web;
  4. namespace SiteCore.URLRewriter
  5. {
  6. public class RewriterModule : IHttpModule
  7. {
  8. public void Init(HttpApplication app)
  9. {
  10. // WARNING! This does not work with Windows authentication!
  11. // If you are using Windows authentication, change to app.BeginRequest
  12. //app.BeginRequest += new EventHandler(app_BeginRequest);
  13. app.AuthorizeRequest += this.URLRewriter;
  14. }
  15. protected void URLRewriter(object sender, EventArgs e)
  16. {
  17. HttpApplication app = (HttpApplication)sender;
  18. string requestedPath = app.Request.Path;
  19. // get the configuration rules
  20. UrlsCollection rules = UrlsConfig.GetConfig().Urls;
  21. for (int i = 0; i < rules.Count; i++)
  22. {
  23. // get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)
  24. string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].VirtualUrl) + "$";
  25. Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
  26. if (re.IsMatch(requestedPath))
  27. {
  28. string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].DestinationUrl));
  29. //if (city != "")
  30. //{
  31. // if(sendToUrl.IndexOf("?")==-1)sendToUrl = sendToUrl + "?city=" + city;
  32. // else sendToUrl = sendToUrl + "&city=" + city;
  33. //}
  34. RewriterUtils.RewriteUrl(app.Context, sendToUrl);
  35. break;
  36. }
  37. }
  38. }
  39. public void Dispose() { }
  40. }
  41. /// <summary>
  42. /// Provides utility helper methods for the rewriting HttpModule and HttpHandler.
  43. /// </summary>
  44. /// <remarks>This class is marked as internal, meaning only classes in the same assembly will be
  45. /// able to access its methods.</remarks>
  46. internal class RewriterUtils
  47. {
  48. #region RewriteUrl
  49. /// <summary>
  50. /// Rewrite's a URL using <b>HttpContext.RewriteUrl()</b>.
  51. /// </summary>
  52. /// <param name="context">The HttpContext object to rewrite the URL to.</param>
  53. /// <param name="sendToUrl">The URL to rewrite to.</param>
  54. internal static void RewriteUrl(HttpContext context, string sendToUrl)
  55. {
  56. string x, y;
  57. RewriteUrl(context, sendToUrl, out x, out y);
  58. }
  59. /// <summary>
  60. /// Rewrite's a URL using <b>HttpContext.RewriteUrl()</b>.
  61. /// </summary>
  62. /// <param name="context">The HttpContext object to rewrite the URL to.</param>
  63. /// <param name="sendToUrl">The URL to rewrite to.</param>
  64. /// <param name="sendToUrlLessQString">Returns the value of sendToUrl stripped of the querystring.</param>
  65. /// <param name="filePath">Returns the physical file path to the requested page.</param>
  66. internal static void RewriteUrl(HttpContext context, string sendToUrl, out string sendToUrlLessQString, out string filePath)
  67. {
  68. // see if we need to add any extra querystring information
  69. if (context.Request.QueryString.Count > 0)
  70. {
  71. if (sendToUrl.IndexOf('?') != -1)
  72. sendToUrl += "&" + context.Request.QueryString;
  73. else
  74. sendToUrl += "?" + context.Request.QueryString;
  75. }
  76. // first strip the querystring, if any
  77. string queryString = String.Empty;
  78. sendToUrlLessQString = sendToUrl;
  79. if (sendToUrl.IndexOf('?') > 0)
  80. {
  81. sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf('?'));
  82. queryString = sendToUrl.Substring(sendToUrl.IndexOf('?') + 1);
  83. }
  84. // grab the file's physical path
  85. filePath = string.Empty;
  86. filePath = context.Server.MapPath(sendToUrlLessQString);
  87. // rewrite the path...
  88. context.RewritePath(sendToUrlLessQString, String.Empty, queryString);
  89. }
  90. #endregion
  91. /// <summary>
  92. /// Converts a URL into one that is usable on the requesting client.
  93. /// </summary>
  94. /// <remarks>Converts ~ to the requesting application path. Mimics the behavior of the
  95. /// <b>Control.ResolveUrl()</b> method, which is often used by control developers.</remarks>
  96. /// <param name="appPath">The application path.</param>
  97. /// <param name="url">The URL, which might contain ~.</param>
  98. /// <returns>A resolved URL. If the input parameter <b>url</b> contains ~, it is replaced with the
  99. /// value of the <b>appPath</b> parameter.</returns>
  100. internal static string ResolveUrl(string appPath, string url)
  101. {
  102. if (url.Length == 0 || url[0] != '~')
  103. return url; // there is no ~ in the first character position, just return the url
  104. else
  105. {
  106. if (url.Length == 1)
  107. return appPath; // there is just the ~ in the URL, return the appPath
  108. if (url[1] == '/' || url[1] == '\\')
  109. {
  110. // url looks like ~/ or ~\
  111. if (appPath.Length > 1)
  112. return appPath + "/" + url.Substring(2);
  113. else
  114. return "/" + url.Substring(2);
  115. }
  116. else
  117. {
  118. // url looks like ~something
  119. if (appPath.Length > 1)
  120. return appPath + "/" + url.Substring(1);
  121. else
  122. return appPath + url.Substring(1);
  123. }
  124. }
  125. }
  126. }
  127. }