//
using System.Web.SessionState;
+using System.Text;
namespace System.Web.Util {
- internal class UrlUtils {
+#if VISUAL_STUDIO
+ public
+#else
+ internal
+#endif
+ class UrlUtils {
// appRoot + SessionID + vpath
- internal static string InsertSessionId (string id, string path)
+ public static string InsertSessionId (string id, string path)
{
string dir = GetDirectory (path);
if (!dir.EndsWith ("/"))
return Canonic (appvpath + "(" + id + ")/" + path);
}
- internal static string GetSessionId (string path)
+ public static string GetSessionId (string path)
{
+#if TARGET_DOTNET
+ return null;
+#else
+ if (path == null)
+ return null;
+
string appvpath = HttpRuntime.AppDomainAppVirtualPath;
- if (path.Length <= appvpath.Length)
+ int appvpathlen = appvpath.Length;
+
+ if (path.Length <= appvpathlen)
return null;
- path = path.Substring (appvpath.Length);
- if (path.Length == 0 || path [0] != '/')
+ path = path.Substring (appvpathlen);
+
+ int len = path.Length;
+ if (len == 0 || path [0] != '/') {
path = '/' + path;
+ len++;
+ }
- int len = path.Length;
if ((len < SessionId.IdLength + 3) || (path [1] != '(') ||
(path [SessionId.IdLength + 2] != ')'))
return null;
return path.Substring (2, SessionId.IdLength);
+#endif
+ }
+
+ public static bool HasSessionId (string path)
+ {
+ if (path == null || path.Length < 5)
+ return false;
+
+ return (StrUtils.StartsWith (path, "/(") && path.IndexOf (")/") > 2);
}
- internal static string RemoveSessionId (string base_path, string file_path)
+ public static string RemoveSessionId (string base_path, string file_path)
{
// Caller did a GetSessionId first
int idx = base_path.IndexOf ("/(");
if (rlength == 0)
return "";
- relPath = relPath.Replace ("\\", "/");
+ relPath = relPath.Replace ('\\', '/');
if (IsRooted (relPath))
return Canonic (relPath);
return Canonic (basePath + slash + relPath);
}
- if (basePath == null || basePath == "" || basePath [0] == '~')
+ if (basePath == null || basePath.Length == 0 || basePath [0] == '~')
basePath = HttpRuntime.AppDomainAppVirtualPath;
if (basePath.Length <= 1)
static char [] path_sep = {'\\', '/'};
- internal static string Canonic (string path)
+ public static string Canonic (string path)
{
+ bool isRooted = IsRooted(path);
+ bool endsWithSlash = path.EndsWith("/");
string [] parts = path.Split (path_sep);
int end = parts.Length;
for (int i = 0; i < end; i++) {
string current = parts [i];
+
+ if (current.Length == 0)
+ continue;
+
if (current == "." )
continue;
if (current == "..") {
- if (dest == 0) {
- if (i == 1) // see bug 52599
- continue;
-
- throw new HttpException ("Invalid path.");
- }
-
dest --;
continue;
}
+ if (dest < 0)
+ if (!isRooted)
+ throw new HttpException ("Invalid path.");
+ else
+ dest = 0;
parts [dest++] = current;
}
+ if (dest < 0)
+ throw new HttpException ("Invalid path.");
if (dest == 0)
return "/";
- return String.Join ("/", parts, 0, dest);
+ string str = String.Join ("/", parts, 0, dest);
+ str = RemoveDoubleSlashes (str);
+ if (isRooted)
+ str = "/" + str;
+ if (endsWithSlash)
+ str = str + "/";
+
+ return str;
}
- internal static string GetDirectory (string url)
+ public static string GetDirectory (string url)
{
url = url.Replace('\\','/');
int last = url.LastIndexOf ('/');
if (last > 0) {
-#if NET_2_0
+ if (last < url.Length)
+ last++;
return RemoveDoubleSlashes (url.Substring (0, last));
-#else
- return url.Substring (0, last);
-#endif
}
return "/";
}
-#if NET_2_0
- internal static string RemoveDoubleSlashes (string input)
+ public static string RemoveDoubleSlashes (string input)
{
// MS VirtualPathUtility removes duplicate '/'
- string str = input;
- string x;
- while ((x = str.Replace ("//", "/")) != str) {
- str = x;
+
+ int index = -1;
+ for (int i = 1; i < input.Length; i++)
+ if (input [i] == '/' && input [i - 1] == '/') {
+ index = i - 1;
+ break;
+ }
+
+ if (index == -1) // common case optimization
+ return input;
+
+ StringBuilder sb = new StringBuilder (input.Length);
+ sb.Append (input, 0, index);
+
+ for (int i = index; i < input.Length; i++) {
+ if (input [i] == '/') {
+ int next = i + 1;
+ if (next < input.Length && input [next] == '/')
+ continue;
+ sb.Append ('/');
+ }
+ else {
+ sb.Append (input [i]);
+ }
}
- return str;
+ return sb.ToString ();
}
-#endif
- internal static string GetFile (string url)
+ public static string GetFile (string url)
{
url = url.Replace('\\','/');
int last = url.LastIndexOf ('/');
return url.Substring (last+1);
}
- throw new Exception (String.Format ("GetFile: `{0}' does not contain a /", url));
+ throw new ArgumentException (String.Format ("GetFile: `{0}' does not contain a /", url));
}
- internal static bool IsRooted (string path)
+ public static bool IsRooted (string path)
{
- if (path == null || path == "")
+ if (path == null || path.Length == 0)
return true;
char c = path [0];
return false;
}
- internal static bool IsRelativeUrl (string path)
+ public static bool IsRelativeUrl (string path)
{
return (path [0] != '/' && path.IndexOf (':') == -1);
}