-//\r
-// System.Net.CredentialCache.cs\r
-//\r
-// Author:\r
-// Lawrence Pit (loz@cable.a2000.nl)\r
-//\r
+//
+// System.Net.CredentialCache.cs
+//
+// Author:
+// Lawrence Pit (loz@cable.a2000.nl)
+//
//
// Permission is hereby granted, free of charge, to any person obtaining
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-\r
-using System;\r
-using System.Collections;\r
-using System.Runtime.Serialization;\r
-\r
-namespace System.Net \r
-{\r
- public class CredentialCache : ICredentials, IEnumerable\r
- {\r
- // Fields\r
- private Hashtable cache;\r
- \r
- // Constructors \r
- public CredentialCache () \r
- {\r
- cache = new Hashtable ();\r
- }\r
- \r
- // Properties\r
- \r
- [MonoTODO ("Need EnvironmentPermission implementation first")]\r
- public static ICredentials DefaultCredentials {\r
- get {\r
- // This is used for NTLM, Kerberos and Negotiate under MS\r
- return null;\r
- }\r
- }\r
- \r
-\r
- // ICredentials\r
-\r
- public NetworkCredential GetCredential (Uri uriPrefix, string authType)\r
- {\r
- int longestPrefix = -1;\r
- NetworkCredential result = null;\r
- \r
- if (uriPrefix == null || authType == null)\r
- return null;\r
- \r
- string absPath = uriPrefix.AbsolutePath;\r
- absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));\r
- \r
- IDictionaryEnumerator e = cache.GetEnumerator ();\r
- while (e.MoveNext ()) {\r
- CredentialCacheKey key = e.Key as CredentialCacheKey;\r
- \r
- if (key.Length <= longestPrefix) \r
- continue;\r
- \r
- if (String.Compare (key.AuthType, authType, true) != 0)\r
- continue;\r
- \r
- Uri cachedUri = key.UriPrefix;\r
- \r
- if (cachedUri.Scheme != uriPrefix.Scheme)\r
- continue;\r
- \r
- if (cachedUri.Port != uriPrefix.Port)\r
- continue;\r
- \r
- if (cachedUri.Host != uriPrefix.Host)\r
- continue;\r
- \r
- if (!absPath.StartsWith (key.AbsPath))\r
- continue;\r
- \r
- longestPrefix = key.Length;\r
- result = (NetworkCredential) e.Value;\r
- }\r
- \r
- return result;\r
- }\r
-\r
- // IEnumerable\r
-\r
- public IEnumerator GetEnumerator ()\r
- {\r
- return cache.Values.GetEnumerator ();\r
- } \r
- \r
- // Methods\r
- \r
- public void Add (Uri uriPrefix, string authType, NetworkCredential cred)\r
- {\r
- if (uriPrefix == null) \r
- throw new ArgumentNullException ("uriPrefix");\r
-\r
- if (authType == null) \r
- throw new ArgumentNullException ("authType");\r
- \r
- // throws ArgumentException when same key already exists.\r
- cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);\r
- }\r
- \r
- public void Remove (Uri uriPrefix, string authType)\r
- {\r
- if (uriPrefix == null) \r
- throw new ArgumentNullException ("uriPrefix");\r
-\r
- if (authType == null) \r
- throw new ArgumentNullException ("authType");\r
-\r
- cache.Remove (new CredentialCacheKey (uriPrefix, authType));\r
- }\r
- \r
- // Inner Classes\r
- \r
- internal class CredentialCacheKey\r
- {\r
- private Uri uriPrefix;\r
- private string authType;\r
- \r
- private string absPath;\r
- private int len;\r
- private int hash;\r
- \r
- internal CredentialCacheKey (Uri uriPrefix, string authType)\r
- {\r
- this.uriPrefix = uriPrefix;\r
- this.authType = authType;\r
- \r
- this.absPath = uriPrefix.AbsolutePath;\r
- this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/')); \r
-\r
- this.len = uriPrefix.AbsoluteUri.Length;\r
- this.hash = uriPrefix.GetHashCode () \r
- + authType.ToString ().GetHashCode ();\r
- }\r
- \r
- public int Length {\r
- get { return len; }\r
- } \r
- \r
- public string AbsPath {\r
- get { return absPath; }\r
- }\r
- \r
- public Uri UriPrefix {\r
- get { return uriPrefix; }\r
- }\r
- \r
- public string AuthType {\r
- get { return authType; }\r
- }\r
- \r
- public override int GetHashCode ()\r
- {\r
- return hash;\r
- }\r
- \r
- public override bool Equals (object obj)\r
- {\r
- CredentialCacheKey key = obj as CredentialCacheKey;\r
- return ((key != null) && (this.hash == key.hash));\r
- }\r
- \r
- public override string ToString ()\r
- {\r
- return absPath + " : " + authType + " : len=" + len;\r
- }\r
- }\r
- } \r
-} \r
-\r
+
+using System;
+using System.Collections;
+using System.Runtime.Serialization;
+
+namespace System.Net {
+ public class CredentialCache : ICredentials, IEnumerable, ICredentialsByHost
+ {
+ static NetworkCredential empty = new NetworkCredential (String.Empty, String.Empty, String.Empty);
+ Hashtable cache;
+ Hashtable cacheForHost;
+
+ public CredentialCache ()
+ {
+ cache = new Hashtable ();
+ cacheForHost = new Hashtable ();
+ }
+
+ [MonoTODO ("Need EnvironmentPermission implementation first")]
+ public static ICredentials DefaultCredentials {
+ get {
+ // This is used for NTLM, Kerberos and Negotiate under MS
+ return empty;
+ }
+ }
+
+ // MS does might return a special ICredentials which does not allow getting the
+ // username/password information out of it for non-internal classes.
+ public static NetworkCredential DefaultNetworkCredentials {
+ get { return empty; }
+ }
+
+ public NetworkCredential GetCredential (Uri uriPrefix, string authType)
+ {
+ int longestPrefix = -1;
+ NetworkCredential result = null;
+
+ if (uriPrefix == null || authType == null)
+ return null;
+
+ string absPath = uriPrefix.AbsolutePath;
+ absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
+
+ IDictionaryEnumerator e = cache.GetEnumerator ();
+ while (e.MoveNext ()) {
+ CredentialCacheKey key = e.Key as CredentialCacheKey;
+
+ if (key.Length <= longestPrefix)
+ continue;
+
+ if (String.Compare (key.AuthType, authType, true) != 0)
+ continue;
+
+ Uri cachedUri = key.UriPrefix;
+
+ if (cachedUri.Scheme != uriPrefix.Scheme)
+ continue;
+
+ if (cachedUri.Port != uriPrefix.Port)
+ continue;
+
+ if (cachedUri.Host != uriPrefix.Host)
+ continue;
+
+ if (!absPath.StartsWith (key.AbsPath))
+ continue;
+
+ longestPrefix = key.Length;
+ result = (NetworkCredential) e.Value;
+ }
+
+ return result;
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return cache.Values.GetEnumerator ();
+ }
+
+ public void Add (Uri uriPrefix, string authType, NetworkCredential cred)
+ {
+ if (uriPrefix == null)
+ throw new ArgumentNullException ("uriPrefix");
+
+ if (authType == null)
+ throw new ArgumentNullException ("authType");
+
+ // throws ArgumentException when same key already exists.
+ cache.Add (new CredentialCacheKey (uriPrefix, authType), cred);
+ }
+
+ public void Remove (Uri uriPrefix, string authType)
+ {
+ if (uriPrefix == null)
+ throw new ArgumentNullException ("uriPrefix");
+
+ if (authType == null)
+ throw new ArgumentNullException ("authType");
+
+ cache.Remove (new CredentialCacheKey (uriPrefix, authType));
+ }
+
+ public NetworkCredential GetCredential (string host, int port, string authenticationType)
+ {
+ NetworkCredential result = null;
+
+ if (host == null || port < 0 || authenticationType == null)
+ return null;
+
+ IDictionaryEnumerator e = cacheForHost.GetEnumerator ();
+ while (e.MoveNext ()) {
+ CredentialCacheForHostKey key = e.Key as CredentialCacheForHostKey;
+
+ if (String.Compare (key.AuthType, authenticationType, true) != 0)
+ continue;
+
+ if (key.Host != host)
+ continue;
+
+ if (key.Port != port)
+ continue;
+
+ result = (NetworkCredential) e.Value;
+ }
+
+ return result;
+ }
+
+ public void Add (string host, int port, string authenticationType, NetworkCredential credential)
+ {
+ if (host == null)
+ throw new ArgumentNullException("host");
+
+ if (port < 0)
+ throw new ArgumentOutOfRangeException("port");
+
+ if (authenticationType == null)
+ throw new ArgumentOutOfRangeException("authenticationType");
+
+ cacheForHost.Add (new CredentialCacheForHostKey (host, port, authenticationType), credential);
+ }
+
+ public void Remove (string host, int port, string authenticationType)
+ {
+ if (host == null)
+ return;
+
+ if (authenticationType == null)
+ return;
+
+ cacheForHost.Remove (new CredentialCacheForHostKey (host, port, authenticationType));
+ }
+
+ class CredentialCacheKey {
+ Uri uriPrefix;
+ string authType;
+ string absPath;
+ int len;
+ int hash;
+
+ internal CredentialCacheKey (Uri uriPrefix, string authType)
+ {
+ this.uriPrefix = uriPrefix;
+ this.authType = authType;
+
+ this.absPath = uriPrefix.AbsolutePath;
+ this.absPath = absPath.Substring (0, absPath.LastIndexOf ('/'));
+
+ this.len = uriPrefix.AbsoluteUri.Length;
+ this.hash = uriPrefix.GetHashCode ()
+ + authType.GetHashCode ();
+ }
+
+ public int Length {
+ get { return len; }
+ }
+
+ public string AbsPath {
+ get { return absPath; }
+ }
+
+ public Uri UriPrefix {
+ get { return uriPrefix; }
+ }
+
+ public string AuthType {
+ get { return authType; }
+ }
+
+ public override int GetHashCode ()
+ {
+ return hash;
+ }
+
+ public override bool Equals (object obj)
+ {
+ CredentialCacheKey key = obj as CredentialCacheKey;
+ return ((key != null) && (this.hash == key.hash));
+ }
+
+ public override string ToString ()
+ {
+ return absPath + " : " + authType + " : len=" + len;
+ }
+ }
+
+ class CredentialCacheForHostKey {
+ string host;
+ int port;
+ string authType;
+ int hash;
+
+ internal CredentialCacheForHostKey (string host, int port, string authType)
+ {
+ this.host = host;
+ this.port = port;
+ this.authType = authType;
+
+ this.hash = host.GetHashCode ()
+ + port.GetHashCode ()
+ + authType.GetHashCode ();
+ }
+
+ public string Host {
+ get { return host; }
+ }
+
+ public int Port {
+ get { return port; }
+ }
+
+ public string AuthType {
+ get { return authType; }
+ }
+
+ public override int GetHashCode ()
+ {
+ return hash;
+ }
+
+ public override bool Equals (object obj)
+ {
+ CredentialCacheForHostKey key = obj as CredentialCacheForHostKey;
+ return ((key != null) && (this.hash == key.hash));
+ }
+
+ public override string ToString ()
+ {
+ return host + " : " + authType;
+ }
+ }
+}
+}
+
+