Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / PathHelpers.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Collections.Specialized;\r
16     using System.Web;\r
17 \r
18     internal static class PathHelpers {\r
19 \r
20         private const string _urlRewriterServerVar = "HTTP_X_ORIGINAL_URL";\r
21 \r
22         // this method can accept an app-relative path or an absolute path for contentPath\r
23         public static string GenerateClientUrl(HttpContextBase httpContext, string contentPath) {\r
24             if (String.IsNullOrEmpty(contentPath)) {\r
25                 return contentPath;\r
26             }\r
27 \r
28             // many of the methods we call internally can't handle query strings properly, so just strip it out for\r
29             // the time being\r
30             string query;\r
31             contentPath = StripQuery(contentPath, out query);\r
32 \r
33             return GenerateClientUrlInternal(httpContext, contentPath) + query;\r
34         }\r
35 \r
36         private static string GenerateClientUrlInternal(HttpContextBase httpContext, string contentPath) {\r
37             if (String.IsNullOrEmpty(contentPath)) {\r
38                 return contentPath;\r
39             }\r
40 \r
41             // can't call VirtualPathUtility.IsAppRelative since it throws on some inputs\r
42             bool isAppRelative = contentPath[0] == '~';\r
43             if (isAppRelative) {\r
44                 string absoluteContentPath = VirtualPathUtility.ToAbsolute(contentPath, httpContext.Request.ApplicationPath);\r
45                 string modifiedAbsoluteContentPath = httpContext.Response.ApplyAppPathModifier(absoluteContentPath);\r
46                 return GenerateClientUrlInternal(httpContext, modifiedAbsoluteContentPath);\r
47             }\r
48 \r
49             // we only want to manipulate the path if URL rewriting is active, else we risk breaking the generated URL\r
50             NameValueCollection serverVars = httpContext.Request.ServerVariables;\r
51             bool urlRewriterIsEnabled = (serverVars != null && serverVars[_urlRewriterServerVar] != null);\r
52             if (!urlRewriterIsEnabled) {\r
53                 return contentPath;\r
54             }\r
55 \r
56             // Since the rawUrl represents what the user sees in his browser, it is what we want to use as the base\r
57             // of our absolute paths. For example, consider mysite.example.com/foo, which is internally\r
58             // rewritten to content.example.com/mysite/foo. When we want to generate a link to ~/bar, we want to\r
59             // base it from / instead of /foo, otherwise the user ends up seeing mysite.example.com/foo/bar,\r
60             // which is incorrect.\r
61             string relativeUrlToDestination = MakeRelative(httpContext.Request.Path, contentPath);\r
62             string absoluteUrlToDestination = MakeAbsolute(httpContext.Request.RawUrl, relativeUrlToDestination);\r
63             return absoluteUrlToDestination;\r
64         }\r
65 \r
66         public static string MakeAbsolute(string basePath, string relativePath) {\r
67             // The Combine() method can't handle query strings on the base path, so we trim it off.\r
68             string query;\r
69             basePath = StripQuery(basePath, out query);\r
70             return VirtualPathUtility.Combine(basePath, relativePath);\r
71         }\r
72 \r
73         public static string MakeRelative(string fromPath, string toPath) {\r
74             string relativeUrl = VirtualPathUtility.MakeRelative(fromPath, toPath);\r
75             if (String.IsNullOrEmpty(relativeUrl) || relativeUrl[0] == '?') {\r
76                 // Sometimes VirtualPathUtility.MakeRelative() will return an empty string when it meant to return '.',\r
77                 // but links to {empty string} are browser dependent. We replace it with an explicit path to force\r
78                 // consistency across browsers.\r
79                 relativeUrl = "./" + relativeUrl;\r
80             }\r
81             return relativeUrl;\r
82         }\r
83 \r
84         private static string StripQuery(string path, out string query) {\r
85             int queryIndex = path.IndexOf('?');\r
86             if (queryIndex >= 0) {\r
87                 query = path.Substring(queryIndex);\r
88                 return path.Substring(0, queryIndex);\r
89             }\r
90             else {\r
91                 query = null;\r
92                 return path;\r
93             }\r
94         }\r
95 \r
96     }\r
97 }\r