2 // System.Web.VirtualPathUtility.cs
\r
5 // Chris Toshok (toshok@ximian.com)
\r
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
\r
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
\r
12 // Permission is hereby granted, free of charge, to any person obtaining
\r
13 // a copy of this software and associated documentation files (the
\r
14 // "Software"), to deal in the Software without restriction, including
\r
15 // without limitation the rights to use, copy, modify, merge, publish,
\r
16 // distribute, sublicense, and/or sell copies of the Software, and to
\r
17 // permit persons to whom the Software is furnished to do so, subject to
\r
18 // the following conditions:
\r
20 // The above copyright notice and this permission notice shall be
\r
21 // included in all copies or substantial portions of the Software.
\r
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
34 using System.Web.Util;
\r
36 namespace System.Web {
\r
38 public static class VirtualPathUtility
\r
40 public static string AppendTrailingSlash (string virtualPath)
\r
42 if (virtualPath == null)
\r
45 int length = virtualPath.Length;
\r
46 if (length == 0 || virtualPath [length - 1] == '/')
\r
49 return virtualPath + "/";
\r
52 public static string Combine (string basePath, string relativePath)
\r
54 if (basePath == null || basePath == "")
\r
55 throw new ArgumentNullException ("basePath");
\r
57 if (relativePath == null)
\r
58 // LAME SPEC - MSDN Specifies ArgumentNullException but MS throws ArgumentException
\r
59 throw new ArgumentException ("relativePath");
\r
61 if (relativePath == "")
\r
62 // MS throw different exception for null or empty string.
\r
63 throw new ArgumentNullException ("relativePath");
\r
65 if (relativePath.Length == 1 && relativePath [0] == '~')
\r
66 return HttpRuntime.AppDomainAppVirtualPath;
\r
68 if (relativePath [0] == '~' && relativePath [1] == '/')
\r
69 return UrlUtils.RemoveDoubleSlashes ((HttpRuntime.AppDomainAppVirtualPath + relativePath.Substring (1)).Replace ('\\', '/'));
\r
71 if (basePath [0] != '/')
\r
72 throw new ArgumentException ("basePath is not an absolute path", "basePath");
\r
74 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/') {
\r
75 int lastSlash = basePath.LastIndexOf ('/');
\r
77 return UrlUtils.Combine (basePath.Substring (0, lastSlash + 1), relativePath);
\r
80 return UrlUtils.Combine (basePath, relativePath);
\r
83 public static string GetDirectory (string virtualPath)
\r
85 if (virtualPath == null || virtualPath == "") // Yes, "" throws an ArgumentNullException
\r
86 throw new ArgumentNullException ("virtualPath");
\r
88 if (virtualPath [0] != '/')
\r
89 throw new ArgumentException ("The virtual path is not rooted", "virtualPath");
\r
91 if (virtualPath == "/")
\r
92 return null; //.net behavior
\r
94 //In .Net - will look for one '/' before the last one, and will return it as a directory
\r
95 //therefor we always should remove the last slash.
\r
96 if (virtualPath.EndsWith("/"))
\r
97 virtualPath = virtualPath.Substring(0, virtualPath.Length - 1);
\r
99 string result = UrlUtils.GetDirectory (virtualPath);
\r
100 return AppendTrailingSlash (result);
\r
103 public static string GetExtension (string virtualPath)
\r
105 if (virtualPath != null && virtualPath != "" &&
\r
106 virtualPath.IndexOf('/') == -1)
\r
108 virtualPath = "./" + virtualPath;
\r
111 string filename = GetFileName (virtualPath);
\r
112 int dot = filename.LastIndexOf ('.');
\r
113 if (dot == -1 || dot == filename.Length + 1)
\r
116 return filename.Substring (dot);
\r
119 public static string GetFileName (string virtualPath)
\r
121 if (virtualPath == null || virtualPath == "") // Yes, "" throws an ArgumentNullException
\r
122 throw new ArgumentNullException ("virtualPath");
\r
124 return UrlUtils.GetFile (RemoveTrailingSlash (virtualPath));
\r
127 public static bool IsAbsolute (string virtualPath)
\r
129 if (virtualPath == "" || virtualPath == null)
\r
130 throw new ArgumentNullException ("virtualPath");
\r
132 return (virtualPath [0] == '/');
\r
135 public static bool IsAppRelative (string virtualPath)
\r
137 if (String.IsNullOrEmpty (virtualPath))
\r
138 throw new ArgumentNullException ("virtualPath");
\r
140 if (virtualPath.Length == 1 && virtualPath [0] == '~')
\r
143 if (virtualPath [0] == '~' && virtualPath [1] == '/')
\r
149 public static string MakeRelative (string fromPath, string toPath)
\r
151 if (fromPath == null || toPath == null)
\r
152 throw new NullReferenceException (); // yeah!
\r
157 if (toPath [0] != '/')
\r
158 throw new ArgumentOutOfRangeException (); // This is what MS does.
\r
160 if (fromPath.Length > 0 && fromPath [0] != '/')
\r
161 throw new ArgumentOutOfRangeException (); // This is what MS does.
\r
163 Uri from = new Uri ("http://nothing" + fromPath);
\r
164 return from.MakeRelativeUri (new Uri ("http://nothing" + toPath)).AbsolutePath;
\r
167 public static string RemoveTrailingSlash (string virtualPath)
\r
169 if (virtualPath == null || virtualPath == "")
\r
172 int last = virtualPath.Length - 1;
\r
173 if (last == 0 || virtualPath [last] != '/')
\r
174 return virtualPath;
\r
176 return virtualPath.Substring (0, last);
\r
179 public static string ToAbsolute (string virtualPath)
\r
181 string apppath = HttpRuntime.AppDomainAppVirtualPath;
\r
182 if (apppath == null)
\r
183 throw new HttpException ("The path to the application is not known");
\r
185 return ToAbsolute (virtualPath,apppath);
\r
188 // If virtualPath is:
\r
189 // Absolute, the ToAbsolute method returns the virtual path with no changes.
\r
190 // Application relative, the ToAbsolute method adds applicationPath to the beginning of the virtual path.
\r
191 // Not rooted, the ToAbsolute method raises an ArgumentOutOfRangeException exception.
\r
192 public static string ToAbsolute (string virtualPath, string applicationPath)
\r
194 if (applicationPath == null || applicationPath == "")
\r
195 throw new ArgumentNullException ("applicationPath");
\r
197 if (virtualPath == null || virtualPath == "")
\r
198 throw new ArgumentNullException ("virtualPath");
\r
200 if (IsAppRelative(virtualPath)) {
\r
201 if (applicationPath [0] != '/')
\r
202 throw new ArgumentException ("appPath is not rooted", "applicationPath");
\r
203 return UrlUtils.RemoveDoubleSlashes ((applicationPath + (virtualPath.Length == 1 ? "/" : virtualPath.Substring (1))).Replace ('\\', '/'));
\r
206 if (virtualPath [0] != '/')
\r
207 throw new ArgumentException (String.Format ("Relative path not allowed: '{0}'", virtualPath));
\r
209 return UrlUtils.RemoveDoubleSlashes (virtualPath.Replace ('\\', '/'));
\r
213 public static string ToAppRelative (string virtualPath)
\r
215 string apppath = HttpRuntime.AppDomainAppVirtualPath;
\r
216 if (apppath == null)
\r
217 throw new HttpException ("The path to the application is not known");
\r
219 return ToAppRelative (apppath, virtualPath);
\r
222 public static string ToAppRelative (string virtualPath, string applicationPath)
\r
224 if (applicationPath == null || applicationPath == "")
\r
225 throw new ArgumentNullException ("applicationPath");
\r
227 if (virtualPath == null || virtualPath == "")
\r
228 throw new ArgumentNullException ("virtualPath");
\r
230 if (virtualPath.StartsWith (".."))
\r
231 throw new ArgumentException (String.Format ("Relative path not allowed: '{0}'", virtualPath));
\r
233 if (applicationPath [0] != '/')
\r
234 throw new ArgumentOutOfRangeException ("appPath is not rooted", "applicationPath");
\r
236 return MakeRelative (applicationPath, virtualPath);
\r