-//\r
-// System.Net.ServicePoint\r
-//\r
-// Authors:\r
-// Lawrence Pit (loz@cable.a2000.nl)\r
-// Gonzalo Paniagua Javier (gonzalo@ximian.com)\r
-//\r
-// (c) 2002 Lawrence Pit\r
-// (c) 2003 Ximian, Inc. (http://www.ximian.com)\r
-//\r
-\r
-using System;\r
-using System.Collections;\r
-using System.Net.Sockets;\r
-using System.Security.Cryptography.X509Certificates;\r
-using System.Threading;\r
-\r
-namespace System.Net \r
-{\r
- public class ServicePoint\r
- {\r
- Uri uri;\r
- int connectionLimit;\r
- int maxIdleTime;\r
- int currentConnections;\r
- DateTime idleSince;\r
- Version protocolVersion;\r
- X509Certificate certificate;\r
- X509Certificate clientCertificate;\r
- IPHostEntry host;\r
- bool usesProxy;\r
- Hashtable groups;\r
- bool sendContinue = true;\r
- \r
- // Constructors\r
-\r
- internal ServicePoint (Uri uri, int connectionLimit, int maxIdleTime)\r
- {\r
- this.uri = uri; \r
- this.connectionLimit = connectionLimit;\r
- this.maxIdleTime = maxIdleTime; \r
- this.currentConnections = 0;\r
- this.idleSince = DateTime.Now;\r
- }\r
- \r
- // Properties\r
- \r
- public Uri Address {\r
- get { return uri; }\r
- }\r
- \r
- public X509Certificate Certificate {\r
- get { return certificate; }\r
- }\r
- \r
- public X509Certificate ClientCertificate {\r
- get { return clientCertificate; }\r
- }\r
- \r
- public int ConnectionLimit {\r
- get { return connectionLimit; }\r
- set {\r
- if (value <= 0)\r
- throw new ArgumentOutOfRangeException ();\r
-\r
- connectionLimit = value;\r
- }\r
- }\r
- \r
- public string ConnectionName {\r
- get { return uri.Scheme; }\r
- }\r
-\r
- public int CurrentConnections {\r
- get {\r
- lock (this) {\r
- return currentConnections;\r
- }\r
- }\r
- }\r
-\r
- public DateTime IdleSince {\r
- get {\r
- lock (this) {\r
- return idleSince;\r
- }\r
- }\r
- }\r
- \r
- public int MaxIdleTime {\r
- get { return maxIdleTime; }\r
- set { \r
- if (value < Timeout.Infinite || value > Int32.MaxValue)\r
- throw new ArgumentOutOfRangeException ();\r
- this.maxIdleTime = value; \r
- }\r
- }\r
- \r
- public virtual Version ProtocolVersion {\r
- get { return protocolVersion; }\r
- }\r
- \r
- public bool SupportsPipelining {\r
- get { return HttpVersion.Version11.Equals (protocolVersion); }\r
- }\r
- \r
- internal bool SendContinue {\r
- get { return sendContinue; }\r
- set { sendContinue = value; }\r
- }\r
- // Methods\r
- \r
- public override int GetHashCode() \r
- {\r
- return base.GetHashCode ();\r
- }\r
- \r
- // Internal Methods\r
-\r
- internal bool UsesProxy {\r
- get { return usesProxy; }\r
- set { usesProxy = value; }\r
- }\r
-\r
- internal bool AvailableForRecycling {\r
- get { \r
- return CurrentConnections == 0\r
- && maxIdleTime != Timeout.Infinite\r
- && DateTime.Now >= IdleSince.AddMilliseconds (maxIdleTime);\r
- }\r
- }\r
-\r
- internal Hashtable Groups {\r
- get {\r
- if (groups == null)\r
- groups = new Hashtable ();\r
-\r
- return groups;\r
- }\r
- }\r
-\r
- internal IPHostEntry HostEntry\r
- {\r
- get {\r
- if (host == null) {\r
- string uriHost = uri.Host;\r
-\r
- // There is no need to do DNS resolution on literal IP addresses\r
- if (uri.HostNameType == UriHostNameType.IPv6 ||\r
- uri.HostNameType == UriHostNameType.IPv4) {\r
-\r
- if (uri.HostNameType == UriHostNameType.IPv6) {\r
- // Remove square brackets\r
- uriHost = uriHost.Substring(1,uriHost.Length-2);\r
- }\r
-\r
- // Creates IPHostEntry\r
- host = new IPHostEntry();\r
- host.AddressList = new IPAddress[] { IPAddress.Parse(uriHost) };\r
-\r
- return host;\r
- }\r
-\r
- // Try DNS resolution on host names\r
- try {\r
- host = Dns.GetHostByName (uriHost);\r
- } \r
- catch {\r
- return null;\r
- }\r
- }\r
-\r
- return host;\r
- }\r
- }\r
-\r
- internal void SetVersion (Version version)\r
- {\r
- protocolVersion = version;\r
- }\r
- \r
- internal WebConnectionGroup GetConnectionGroup (string name)\r
- {\r
- if (name == null)\r
- name = "";\r
-\r
- WebConnectionGroup group = Groups [name] as WebConnectionGroup;\r
- if (group != null)\r
- return group;\r
-\r
- group = new WebConnectionGroup (this, name);\r
- Groups [name] = group;\r
- return group;\r
- }\r
-\r
- internal EventHandler SendRequest (HttpWebRequest request, string groupName)\r
- {\r
- WebConnection cnc;\r
- \r
- lock (this) {\r
- WebConnectionGroup cncGroup = GetConnectionGroup (groupName);\r
- cnc = cncGroup.GetConnection ();\r
- }\r
- \r
- return cnc.SendRequest (request);\r
- }\r
-\r
- internal void IncrementConnection ()\r
- {\r
- lock (this) {\r
- currentConnections++;\r
- idleSince = DateTime.Now.AddMilliseconds (1000000);\r
- Console.WriteLine ("+CurerntCnc: {0} {1}", Address, currentConnections);\r
- }\r
- }\r
-\r
- internal void DecrementConnection ()\r
- {\r
- lock (this) {\r
- currentConnections--;\r
- if (currentConnections == 0)\r
- idleSince = DateTime.Now;\r
- Console.WriteLine ("-CurerntCnc: {0} {1}", Address, currentConnections);\r
- }\r
+//
+// System.Net.ServicePoint
+//
+// Authors:
+// Lawrence Pit (loz@cable.a2000.nl)
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2002 Lawrence Pit
+// (c) 2003 Ximian, Inc. (http://www.ximian.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections;
+using System.Net.Sockets;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+
+namespace System.Net
+{
+ public class ServicePoint
+ {
+ Uri uri;
+ int connectionLimit;
+ int maxIdleTime;
+ int currentConnections;
+ DateTime idleSince;
+ Version protocolVersion;
+ X509Certificate certificate;
+ X509Certificate clientCertificate;
+ IPHostEntry host;
+ bool usesProxy;
+ Hashtable groups;
+ bool sendContinue = true;
+ bool useConnect;
+ object locker = new object ();
+ object hostE = new object ();
+#if NET_1_1
+ bool useNagle;
+#endif
+#if NET_2_0
+ BindIPEndPoint endPointCallback = null;
+#endif
+
+ // Constructors
+
+ internal ServicePoint (Uri uri, int connectionLimit, int maxIdleTime)
+ {
+ this.uri = uri;
+ this.connectionLimit = connectionLimit;
+ this.maxIdleTime = maxIdleTime;
+ this.currentConnections = 0;
+ this.idleSince = DateTime.Now;
+ }
+
+ // Properties
+
+ public Uri Address {
+ get { return uri; }
+ }
+
+#if NET_2_0
+ static Exception GetMustImplement ()
+ {
+ return new NotImplementedException ();
+ }
+
+ public BindIPEndPoint BindIPEndPointDelegate
+ {
+ get { return endPointCallback; }
+ set { endPointCallback = value; }
+ }
+#endif
+
+ public X509Certificate Certificate {
+ get { return certificate; }
+ }
+
+ public X509Certificate ClientCertificate {
+ get { return clientCertificate; }
+ }
+
+#if NET_2_0
+ [MonoTODO]
+ public int ConnectionLeaseTimeout
+ {
+ get {
+ throw GetMustImplement ();
+ }
+ set {
+ throw GetMustImplement ();
+ }
+ }
+#endif
+
+ public int ConnectionLimit {
+ get { return connectionLimit; }
+ set {
+ if (value <= 0)
+ throw new ArgumentOutOfRangeException ();
+
+ connectionLimit = value;
+ }
+ }
+
+ public string ConnectionName {
+ get { return uri.Scheme; }
+ }
+
+ public int CurrentConnections {
+ get {
+ return currentConnections;
+ }
+ }
+
+ public DateTime IdleSince {
+ get {
+ return idleSince;
+ }
+ internal set {
+ lock (locker)
+ idleSince = value;
+ }
+ }
+
+ public int MaxIdleTime {
+ get { return maxIdleTime; }
+ set {
+ if (value < Timeout.Infinite || value > Int32.MaxValue)
+ throw new ArgumentOutOfRangeException ();
+ this.maxIdleTime = value;
+ }
+ }
+
+ public virtual Version ProtocolVersion {
+ get { return protocolVersion; }
+ }
+
+#if NET_2_0
+ [MonoTODO]
+ public int ReceiveBufferSize
+ {
+ get {
+ throw GetMustImplement ();
+ }
+ set {
+ throw GetMustImplement ();
+ }
+ }
+#endif
+
+ public bool SupportsPipelining {
+ get { return HttpVersion.Version11.Equals (protocolVersion); }
+ }
+
+#if NET_1_1
+ public bool Expect100Continue {
+ get { return SendContinue; }
+ set { SendContinue = value; }
+ }
+
+ public bool UseNagleAlgorithm {
+ get { return useNagle; }
+ set { useNagle = value; }
+ }
+#endif
+
+ internal bool SendContinue {
+ get { return sendContinue &&
+ (protocolVersion == null || protocolVersion == HttpVersion.Version11); }
+ set { sendContinue = value; }
+ }
+ // Methods
+
+#if !NET_2_0
+ public override int GetHashCode()
+ {
+ return base.GetHashCode ();
+ }
+#endif
+
+ // Internal Methods
+
+ internal bool UsesProxy {
+ get { return usesProxy; }
+ set { usesProxy = value; }
+ }
+
+ internal bool UseConnect {
+ get { return useConnect; }
+ set { useConnect = value; }
+ }
+
+ internal bool AvailableForRecycling {
+ get {
+ return CurrentConnections == 0
+ && maxIdleTime != Timeout.Infinite
+ && DateTime.Now >= IdleSince.AddMilliseconds (maxIdleTime);
+ }
+ }
+
+ internal Hashtable Groups {
+ get {
+ if (groups == null)
+ groups = new Hashtable ();
+
+ return groups;
+ }
+ }
+
+ 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 (uri.HostNameType == UriHostNameType.IPv6) {
+ // Remove square brackets
+ uriHost = uriHost.Substring(1,uriHost.Length-2);
+ }
+
+ // 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;
+ }
+ }
+
+ return host;
+ }
+ }
+
+ internal void SetVersion (Version version)
+ {
+ protocolVersion = version;
+ }
+
+#if !TARGET_JVM
+ WebConnectionGroup GetConnectionGroup (string name)
+ {
+ if (name == null)
+ name = "";
+
+ WebConnectionGroup group = Groups [name] as WebConnectionGroup;
+ if (group != null)
+ return group;
+
+ group = new WebConnectionGroup (this, name);
+ Groups [name] = group;
+ return group;
+ }
+
+ internal EventHandler SendRequest (HttpWebRequest request, string groupName)
+ {
+ WebConnection cnc;
+
+ lock (locker) {
+ WebConnectionGroup cncGroup = GetConnectionGroup (groupName);
+ cnc = cncGroup.GetConnection (request);
+ }
+
+ return cnc.SendRequest (request);
+ }
+#endif
+#if NET_2_0
+ public bool CloseConnectionGroup (string connectionGroupName)
+ {
+ lock (locker) {
+ WebConnectionGroup cncGroup = GetConnectionGroup (connectionGroupName);
+ if (cncGroup != null) {
+ cncGroup.Close ();
+ return true;
+ }
+ }
+
+ return false;
+ }
+#endif
+
+ internal void IncrementConnection ()
+ {
+ lock (locker) {
+ currentConnections++;
+ idleSince = DateTime.Now.AddMilliseconds (1000000);
+ }
+ }
+
+ internal void DecrementConnection ()
+ {
+ lock (locker) {
+ currentConnections--;
+ if (currentConnections == 0)
+ idleSince = DateTime.Now;
+ }
}
internal void SetCertificates (X509Certificate client, X509Certificate server)
{
- certificate = server;\r
- clientCertificate = client;\r
- }\r
- }\r
-}\r
+ certificate = server;
+ clientCertificate = client;
+ }
+
+#if NET_2_0
+ internal bool CallEndPointDelegate (Socket sock, IPEndPoint remote)
+ {
+ if (endPointCallback == null)
+ return true;
+
+ int count = 0;
+ for (;;) {
+ IPEndPoint local = null;
+ try {
+ local = endPointCallback (this,
+ remote, count);
+ } catch {
+ // This is to differentiate from an
+ // OverflowException, which should propagate.
+ return false;
+ }
+
+ if (local == null)
+ return true;
+
+ try {
+ sock.Bind (local);
+ } catch (SocketException) {
+ // This is intentional; the docs say
+ // that if the Bind fails, we keep
+ // going until there is an
+ // OverflowException on the retry
+ // count.
+ checked { ++count; }
+ continue;
+ }
+
+ return true;
+ }
+ }
+#endif
+ }
+}
+
+