Merge pull request #2092 from kasthack/system-web-stuff-import
[mono.git] / mcs / class / System / System.Net / ServicePoint.cs
index 26a98ac353fa613f9716b483365ac0683878fe28..ebac3e9cf1d2760763fd5753cd4c47763de54c71 100644 (file)
@@ -47,6 +47,7 @@ namespace System.Net
                int maxIdleTime;
                int currentConnections;
                DateTime idleSince;
+               DateTime lastDnsResolve;
                Version protocolVersion;
                X509Certificate certificate;
                X509Certificate clientCertificate;
@@ -275,7 +276,7 @@ namespace System.Net
                        groups.Remove (group.Name);
                }
 
-               internal bool CheckAvailableForRecycling (out DateTime outIdleSince)
+               bool CheckAvailableForRecycling (out DateTime outIdleSince)
                {
                        outIdleSince = DateTime.MinValue;
 
@@ -312,9 +313,10 @@ namespace System.Net
                        lock (this) {
                                idleSince = outIdleSince;
 
-                               if (removeList != null) {
+                               if (removeList != null && groups != null) {
                                        foreach (var group in removeList)
-                                               RemoveConnectionGroup (group);
+                                               if (groups.ContainsKey (group.Name))
+                                                       RemoveConnectionGroup (group);
                                }
 
                                if (groups != null && groups.Count == 0)
@@ -338,37 +340,30 @@ namespace System.Net
                        CheckAvailableForRecycling (out dummy);
                }
 
+               private bool HasTimedOut
+               {
+                       get {
+                               int timeout = ServicePointManager.DnsRefreshTimeout;
+                               return timeout != Timeout.Infinite &&
+                                       (lastDnsResolve + TimeSpan.FromMilliseconds (timeout)) < DateTime.UtcNow;
+                       }
+               }
+
                internal IPHostEntry HostEntry
                {
                        get {
                                lock (hostE) {
-                                       if (host != null)
-                                               return host;
-
                                        string uriHost = uri.Host;
 
-                                       // There is no need to do DNS resolution on literal IP addresses
-                                       if (uri.HostNameType == UriHostNameType.IPv6 ||
-                                               uri.HostNameType == UriHostNameType.IPv4) {
+                                       if (host == null || HasTimedOut) {
+                                               lastDnsResolve = DateTime.UtcNow;
 
-                                               if (uri.HostNameType == UriHostNameType.IPv6) {
-                                                       // Remove square brackets
-                                                       uriHost = uriHost.Substring(1,uriHost.Length-2);
+                                               try {
+                                                       host = Dns.GetHostEntry (uriHost);
+                                               }
+                                               catch (Exception) {
+                                                       return null;
                                                }
-
-                                               // Creates IPHostEntry
-                                               host = new IPHostEntry();
-                                               host.AddressList = new IPAddress[] { IPAddress.Parse(uriHost) };
-
-                                               return host;
-                                       }
-
-                                       // Try DNS resolution on host names
-                                       try  {
-                                               host = Dns.GetHostByName (uriHost);
-                                       } 
-                                       catch {
-                                               return null;
                                        }
                                }
 
@@ -400,15 +395,21 @@ namespace System.Net
                }
                public bool CloseConnectionGroup (string connectionGroupName)
                {
+                       WebConnectionGroup cncGroup = null;
+
                        lock (this) {
-                               WebConnectionGroup cncGroup = GetConnectionGroup (connectionGroupName);
+                               cncGroup = GetConnectionGroup (connectionGroupName);
                                if (cncGroup != null) {
-                                       cncGroup.Close ();
                                        RemoveConnectionGroup (cncGroup);
-                                       return true;
                                }
                        }
 
+                       // WebConnectionGroup.Close() must *not* be called inside the lock
+                       if (cncGroup != null) {
+                               cncGroup.Close ();
+                               return true;
+                       }
+
                        return false;
                }