using System.Net;
using System.Runtime.Serialization;
using System.Text;
+using System.Collections;
// See RFC 2396 for more info on URI's.
host = EscapeString (host, false, true, false);
path = EscapeString (path);
- query = EscapeString (query);
- fragment = EscapeString (fragment, false, false, true);
}
public Uri (Uri baseUri, string relativeUri)
userEscaped = dontEscape;
- this.scheme = baseUri.scheme;
- this.host = baseUri.host;
- this.port = baseUri.port;
- this.userinfo = baseUri.userinfo;
- this.isUnc = baseUri.isUnc;
- this.isWindowsFilePath = baseUri.isWindowsFilePath;
- this.isUnixFilePath = baseUri.isUnixFilePath;
- this.isOpaquePart = baseUri.isOpaquePart;
-
if (relativeUri == null)
throw new NullReferenceException ("relativeUri");
- if (relativeUri == String.Empty) {
- this.path = baseUri.path;
- this.query = baseUri.query;
- this.fragment = baseUri.fragment;
- return;
- }
-
int pos = relativeUri.IndexOf (':');
if (pos != -1) {
host = EscapeString (host, false, true, false);
path = EscapeString (path);
- query = EscapeString (query);
- fragment = EscapeString (fragment, false, false, true);
return;
}
}
+ this.scheme = baseUri.scheme;
+ this.host = baseUri.host;
+ this.port = baseUri.port;
+ this.userinfo = baseUri.userinfo;
+ this.isUnc = baseUri.isUnc;
+ this.isWindowsFilePath = baseUri.isWindowsFilePath;
+ this.isUnixFilePath = baseUri.isUnixFilePath;
+ this.isOpaquePart = baseUri.isOpaquePart;
+
+ if (relativeUri == String.Empty) {
+ this.path = baseUri.path;
+ this.query = baseUri.query;
+ this.fragment = baseUri.fragment;
+ return;
+ }
+
// 8 fragment
pos = relativeUri.IndexOf ('#');
if (pos != -1) {
fragment = relativeUri.Substring (pos);
- if (!userEscaped)
- fragment = EscapeString (fragment, false, false, true);
relativeUri = relativeUri.Substring (0, pos);
}
}
// Properties
-
+
public string AbsolutePath {
get { return path; }
}
public string AbsoluteUri {
- get {
- if (cachedAbsoluteUri == null)
- cachedAbsoluteUri = GetLeftPart (UriPartial.Path) + query + fragment;
+ get {
+ if (cachedAbsoluteUri == null) {
+// cachedAbsoluteUri = GetLeftPart (UriPartial.Path) + query + fragment;
+ string qf = IsFile ? query + fragment : EscapeString (query + fragment);
+ cachedAbsoluteUri = GetLeftPart (UriPartial.Path) + qf;
+ }
return cachedAbsoluteUri;
}
}
return true;
try {
- return IPAddress.IsLoopback (IPAddress.Parse (host));
+ if (IPAddress.Loopback.Equals (IPAddress.Parse (host)))
+ return true;
} catch (FormatException) {}
try {
get {
if (!IsFile)
return path;
+
+ bool windows = (path.Length > 3 && path [1] == ':' &&
+ (path [2] == '\\' || path [2] == '/'));
+
if (!IsUnc) {
string p = Unescape (path);
- if (System.IO.Path.DirectorySeparatorChar == '\\')
+ if (System.IO.Path.DirectorySeparatorChar == '\\' || windows)
return p.Replace ('/', '\\');
else
return p;
uri = new Uri (s);
}
- return ((this.scheme == uri.scheme) &&
- (this.userinfo == uri.userinfo) &&
- (this.host == uri.host) &&
- (this.port == uri.port) &&
- (this.path == uri.path) &&
- (this.query == uri.query));
+ return ((this.scheme.ToLower () == uri.scheme.ToLower ()) &&
+ (this.userinfo.ToLower () == uri.userinfo.ToLower ()) &&
+ (this.host.ToLower () == uri.host.ToLower ()) &&
+ (this.port == uri.port) &&
+ (this.path == uri.path) &&
+ (this.query.ToLower () == uri.query.ToLower ()));
}
public override int GetHashCode ()
{
if (cachedToString != null)
return cachedToString;
- if (IsFile && !IsUnc)
- cachedToString = Unescape (AbsoluteUri);
- else
- cachedToString = AbsoluteUri;
+ cachedToString = Unescape (AbsoluteUri);
return cachedToString;
}
if (str == null)
return String.Empty;
+ byte [] data = Encoding.UTF8.GetBytes (str.ToCharArray ());
StringBuilder s = new StringBuilder ();
- int len = str.Length;
+ int len = data.Length;
for (int i = 0; i < len; i++) {
- char c = str [i];
+ char c = (char) data [i];
// reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
// control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
s.Append (HexUnescape (str, ref i));
i--;
} else
- s.Append (c);
+ s.Append (c);
}
return s.ToString ();
}
} else if (scheme == UriSchemeFile) {
isUnc = true;
}
+
+ if ((scheme != Uri.UriSchemeMailto) &&
+ (scheme != Uri.UriSchemeNews) &&
+ (scheme != Uri.UriSchemeFile))
+ path = Reduce (path);
}
+ private static string Reduce (string path)
+ {
+ path = path.Replace ('\\','/');
+ string [] parts = path.Split ('/');
+ ArrayList result = new ArrayList ();
+
+ int end = parts.Length;
+ for (int i = 0; i < end; i++) {
+ string current = parts [i];
+ if (current == "" || current == "." )
+ continue;
+
+ if (current == "..") {
+ if (result.Count == 0) {
+ if (i == 1) // see bug 52599
+ continue;
+ throw new Exception ("Invalid path.");
+ }
+
+ result.RemoveAt (result.Count - 1);
+ continue;
+ }
+
+ result.Add (current);
+ }
+
+ if (result.Count == 0)
+ return "/";
+
+ result.Insert (0, "");
+
+ string res = String.Join ("/", (string []) result.ToArray (typeof (string)));
+ if (path.EndsWith ("/"))
+ res += '/';
+
+ return res;
+ }
private struct UriScheme
{