1: using System.Text.RegularExpressions;
2: using System.Web;
3:
4: namespace SquaredRoot.Mvc.Extensions.Ssl
5: {
6: /// <summary>
7: /// Provides helper extensions for turning strings into fully-qualified and SSL-enabled Urls.
8: /// </summary>
9: public static class UrlStringExtensions
10: {
11: /// <summary>
12: /// Takes a relative or absolute url and returns the fully-qualified url path.
13: /// </summary>
14: /// <param name="text">The url to make fully-qualified. Ex: Home/About</param>
15: /// <returns>The absolute url plus protocol, server, & port. Ex: http://localhost:1234/Home/About</returns>
16: public static string ToFullyQualifiedUrl( this string text )
17: {
18: //### the VirtualPathUtility doesn"t handle querystrings, so we break the original url up
19: var oldUrl = text;
20: var oldUrlArray = ( oldUrl.Contains( "?" ) ? oldUrl.Split( '?' ) : new[]{ oldUrl, "" } );
21:
22: //### we"ll use the Request.Url object to recreate the current server request"s base url
23: //### requestUri.AbsoluteUri = "http://domain.com:1234/Home/Index"
24: //### requestUri.LocalPath = "/Home/Index"
25: //### subtract the two and you get "http://domain.com:1234", which is urlBase
26: var requestUri = HttpContext.Current.Request.Url;
27: //### fix for Mike Hadlow's reported issue regarding extraneous link elements when a querystring is present
28: //var urlBase = requestUri.AbsoluteUri.Substring( 0, requestUri.AbsoluteUri.Length - requestUri.LocalPath.Length );
29: var localPathAndQuery = requestUri.LocalPath + requestUri.Query;
30: var urlBase = requestUri.AbsoluteUri.Substring( 0, requestUri.AbsoluteUri.Length - localPathAndQuery.Length );
31:
32: //### convert the request url into an absolute path, then reappend the querystring, if one was specified
33: var newUrl = VirtualPathUtility.ToAbsolute( oldUrlArray[0] );
34: if( !string.IsNullOrEmpty( oldUrlArray[1] ) )
35: newUrl += "?" + oldUrlArray[1];
36:
37: //### combine the old url base (protocol + server + port) with the new local path
38: return urlBase + newUrl;
39: }
40:
41: /// <summary>
42: /// Looks for Html links in the passed string and turns each relative or absolute url and returns the fully-qualified url path.
43: /// </summary>
44: /// <param name="text">The url to make fully-qualified. Ex: <a href="Home/About">Blah</a></param>
45: /// <returns>The absolute url plus protocol, server, & port. Ex: <a href="http://localhost:1234/Home/About">Blah</a></returns>
46: public static string ToFullyQualifiedLink( this string text )
47: {
48: var regex = new Regex(
49: "(?<Before><a.*href=\")(?!http)(?<Url>.*?)(?<After>\".+>)",
50: RegexOptions.Multiline | RegexOptions.IgnoreCase
51: );
52:
53: return regex.Replace( text, ( Match m ) =>
54: m.Groups["Before"].Value +
55: ToFullyQualifiedUrl( m.Groups["Url"].Value ) +
56: m.Groups["After"].Value
57: );
58: }
59:
60: /// <summary>
61: /// Takes a relative or absolute url and returns the fully-qualified url path using the Https protocol.
62: /// </summary>
63: /// <param name="text">The url to make fully-qualified. Ex: Home/About</param>
64: /// <returns>The absolute url plus server, & port using the Https protocol. Ex: https://localhost:1234/Home/About</returns>
65: public static string ToSslUrl( this string text )
66: {
67: return ToFullyQualifiedUrl( text ).Replace( "http:", "https:" );
68: }
69:
70: /// <summary>
71: /// Looks for Html links in the passed string and turns each relative or absolute url into a fully-qualified url path using the Https protocol.
72: /// </summary>
73: /// <param name="text">The url to make fully-qualified. Ex: <a href="Home/About">Blah</a></param>
74: /// <returns>The absolute url plus server, & port using the Https protocol. Ex: <a href="https://localhost:1234/Home/About">Blah</a></returns>
75: public static string ToSslLink( this string text )
76: {
77: return ToFullyQualifiedLink( text ).Replace( "http:", "https:" );
78: }
79: }
80: }