Merge pull request #472 from MelanieT/spmanager_fix
[mono.git] / mcs / class / System / System.Net / WebConnectionGroup.cs
index 86e64d5ba8881fea711eed0099e2dcf36791317e..ee17b99816641e96697ed91b7c2396e8def5aa5c 100644 (file)
@@ -5,6 +5,7 @@
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
 // (C) 2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
 //
 
 //
@@ -51,7 +52,27 @@ namespace System.Net
                        queue = new Queue ();
                }
 
-               public WebConnection GetConnection ()
+               public void Close ()
+               {
+                       //TODO: what do we do with the queue? Empty it out and abort the requests?
+                       //TODO: abort requests or wait for them to finish
+                       lock (connections) {
+                               WeakReference cncRef = null;
+
+                               int end = connections.Count;
+                               // ArrayList removed = null;
+                               for (int i = 0; i < end; i++) {
+                                       cncRef = (WeakReference) connections [i];
+                                       WebConnection cnc = cncRef.Target as WebConnection;
+                                       if (cnc != null) {
+                                               cnc.Close (false);
+                                       }
+                               }
+                               connections.Clear ();
+                       }
+               }
+
+               public WebConnection GetConnection (HttpWebRequest request)
                {
                        WebConnection cnc = null;
                        lock (connections) {
@@ -76,13 +97,42 @@ namespace System.Net
                                                connections.RemoveAt ((int) removed [i]);
                                }
 
-                               cnc = CreateOrReuseConnection ();
+                               cnc = CreateOrReuseConnection (request);
                        }
 
                        return cnc;
                }
 
-               WebConnection CreateOrReuseConnection ()
+               static void PrepareSharingNtlm (WebConnection cnc, HttpWebRequest request)
+               {
+                       if (!cnc.NtlmAuthenticated)
+                               return;
+
+                       bool needs_reset = false;
+                       NetworkCredential cnc_cred = cnc.NtlmCredential;
+
+                       bool isProxy = (request.Proxy != null && !request.Proxy.IsBypassed (request.RequestUri));
+                       ICredentials req_icreds = (!isProxy) ? request.Credentials : request.Proxy.Credentials;
+                       NetworkCredential req_cred = (req_icreds != null) ? req_icreds.GetCredential (request.RequestUri, "NTLM") : null;
+
+                       if (cnc_cred == null || req_cred == null ||
+                               cnc_cred.Domain != req_cred.Domain || cnc_cred.UserName != req_cred.UserName ||
+                               cnc_cred.Password != req_cred.Password) {
+                               needs_reset = true;
+                       }
+
+                       if (!needs_reset) {
+                               bool req_sharing = request.UnsafeAuthenticatedConnectionSharing;
+                               bool cnc_sharing = cnc.UnsafeAuthenticatedConnectionSharing;
+                               needs_reset = (req_sharing == false || req_sharing != cnc_sharing);
+                       }
+                       if (needs_reset) {
+                               cnc.Close (false); // closes the authenticated connection
+                               cnc.ResetNtlm ();
+                       }
+               }
+
+               WebConnection CreateOrReuseConnection (HttpWebRequest request)
                {
                        // lock is up there.
                        WebConnection cnc;
@@ -102,6 +152,7 @@ namespace System.Net
                                if (cnc.Busy)
                                        continue;
 
+                               PrepareSharingNtlm (cnc, request);
                                return cnc;
                        }
 
@@ -114,7 +165,7 @@ namespace System.Net
                        if (rnd == null)
                                rnd = new Random ();
 
-                       int idx = (count > 1) ? rnd.Next (0, count - 1) : 0;
+                       int idx = (count > 1) ? rnd.Next (0, count) : 0;
                        cncRef = (WeakReference) connections [idx];
                        cnc = cncRef.Target as WebConnection;
                        if (cnc == null) {