2 * Namespace: System.Web.UI.Util
\r
5 * Author: Gaurav Vaish
\r
6 * Maintainer: gvaish@iitk.ac.in
\r
9 * (C) Gaurav Vaish (2001)
\r
13 using System.Collections;
\r
16 namespace System.Web.Util
\r
18 internal class UrlUtils
\r
21 * I could not find these functions in the class System.Uri
\r
22 * Besides, an instance of Uri will not be formed until and unless the address is of
\r
23 * the form protocol://[user:pass]host[:port]/[fullpath]
\r
24 * ie, a protocol, and that too without any blanks before,
\r
25 * is a must which may not be the case here.
\r
26 * Important: Escaped URL is assumed here. nothing like .aspx?path=/something
\r
27 * It should be .aspx?path=%2Fsomething
\r
29 public static string GetProtocol(string url)
\r
31 //Taking code from Java Class java.net.URL
\r
37 int i, start = 0, limit;
\r
41 while( (limit > 0) && (url[limit-1] <= ' '))
\r
45 while( (start < limit) && (url[start] <= ' '))
\r
49 if(RegionMatches(true, url, start, "url:", 0, 4))
\r
53 if(start < url.Length && url[start]=='#')
\r
57 for(i = start; !aRef && (i < limit) && ((c=url[i]) != '/'); i++)
\r
61 return url.Substring(start, i - start);
\r
66 return String.Empty;
\r
69 public static bool IsRelativeUrl(string url)
\r
71 if(url.IndexOf(':') != -1)
\r
72 return !IsRootUrl(url);
\r
76 public static bool IsRootUrl(string url)
\r
82 return IsValidProtocol(GetProtocol(url).ToLower());
\r
88 public static bool IsRooted(string path)
\r
90 if(path!=null && path.Length > 0)
\r
92 return (path[0]=='/' || path[0]=='\\');
\r
97 public static void FailIfPhysicalPath(string path)
\r
99 if(path!= null && path.Length > 0)
\r
101 if(path[0]==':' || path.StartsWith(@"\\"))
\r
102 throw new HttpException(HttpRuntime.FormatResourceString("Physical_path_not_allowed", path));
\r
106 public static string Combine(string basePath, string relPath)
\r
108 FailIfPhysicalPath(relPath);
\r
109 if(IsRootUrl(relPath))
\r
111 if(relPath != null && relPath.Length > 0)
\r
113 return Reduce(relPath);
\r
115 return String.Empty;
\r
117 if(relPath.Length < 3 || relPath[0]!='~' || (relPath[0]!='/' && relPath[0]!='\\'))
\r
119 if(basePath==null || basePath.Length==1 || basePath[0]=='/')
\r
120 basePath = String.Empty;
\r
121 return Reduce(basePath + "/" + relPath);
\r
123 string vPath = HttpRuntime.AppDomainAppVirtualPath;
\r
124 if(vPath.Length <= 1)
\r
125 vPath = String.Empty;
\r
126 return Reduce(vPath + "/" + relPath.Substring(2));
\r
129 public static bool IsValidProtocol(string protocol)
\r
131 if(protocol.Length < 1)
\r
133 char c = protocol[0];
\r
134 if(!Char.IsLetter(c))
\r
138 for(int i=1; i < protocol.Length; i++)
\r
141 if(!Char.IsLetterOrDigit(c) && c!='.' && c!='+' && c!='-')
\r
150 * MakeRelative("http://www.foo.com/bar1/bar2/file","http://www.foo.com/bar1")
\r
151 * will return "bar2/file"
\r
152 * while MakeRelative("http://www.foo.com/bar1/...","http://www.anotherfoo.com")
\r
153 * return 'null' and so does the call
\r
154 * MakeRelative("http://www.foo.com/bar1/bar2","http://www.foo.com/bar")
\r
156 public static string MakeRelative(string fullUrl, string relativeTo)
\r
158 if(fullUrl==relativeTo)
\r
160 return String.Empty;
\r
162 if(fullUrl.IndexOf(relativeTo)!=0)
\r
166 string leftOver = fullUrl.Substring(relativeTo.Length);
\r
167 if(!fullUrl.EndsWith("/") && !leftOver.StartsWith("/"))
\r
171 if(leftOver.StartsWith("/"))
\r
173 leftOver = leftOver.Substring(1);
\r
179 * Check JavaDocs for java.lang.String#RegionMatches(bool, int, String, int, int)
\r
180 * Could not find anything similar in the System.String class
\r
182 public static bool RegionMatches(bool ignoreCase, string source, int start, string match, int offset, int len)
\r
184 if(source!=null || match!=null)
\r
186 if(source.Length>0 && match.Length>0)
\r
188 char[] ta = source.ToCharArray();
\r
189 char[] pa = match.ToCharArray();
\r
190 if((offset < 0) || (start < 0) || (start > (source.Length - len)) || (offset > (match.Length - len)))
\r
196 char c1 = ta[start++];
\r
197 char c2 = pa[offset++];
\r
202 if(Char.ToUpper(c1)==Char.ToUpper(c2))
\r
204 // Check for Gregorian Calendar where the above may not hold good
\r
205 if(Char.ToLower(c1)==Char.ToLower(c2))
\r
216 public static string Reduce(string path)
\r
218 int len = path.Length;
\r
220 path = path.Replace('\\','/');
\r
224 dotIndex = path.IndexOf('.', dotIndex);
\r
229 if(dotIndex != 0 && path[dotIndex -1]=='/')
\r
231 if(dotIndex+1 == len || path[dotIndex+1]=='/')
\r
233 if(path[dotIndex+1]=='.')
\r
235 if(dotIndex+2 == len || path[dotIndex+2]=='/')
\r
238 ArrayList list = new ArrayList();
\r
239 StringBuilder sb = new StringBuilder();
\r
245 dotIndex = path.IndexOf('/', temp + 1);
\r
248 if( (dotIndex - temp) <= 3 && (dotIndex < 1 || path[dotIndex - 1]== '.') && ( (temp+1) >= len || path[temp+1]=='.') )
\r
250 if(dotIndex - temp == 3)
\r
252 if(list.Count == 0)
\r
253 throw new System.Web.HttpException(System.Web.HttpRuntime.FormatResourceString("Cannot_exit_up_top_directory"));
\r
254 sb.Length = (int) list[list.Count - 1];
\r
255 list.RemoveRange(list.Count - 1, 1);
\r
258 list.Add(sb.Length);
\r
259 sb.Append(path, temp, dotIndex - temp);
\r
260 } while(dotIndex != len);
\r
261 return sb.ToString();
\r
264 public static string GetDirectory(string url)
\r
272 return String.Empty;
\r
274 url.Replace('\\','/');
\r
275 string baseDir = url.Substring(0, url.LastIndexOf('/'));
\r
276 if(baseDir.Length==0)
\r