Merge branch 'master' into msbuilddll2
[mono.git] / mcs / class / System / System.Net / HttpWebRequest.cs
index 3f027fa8c28c9d9c45d6fe649392d362250c9867..1cdffff53304462ef786183bc0e62467ed06c10b 100644 (file)
@@ -36,6 +36,7 @@ using System.Collections;
 using System.Configuration;
 using System.Globalization;
 using System.IO;
+using System.Net;
 using System.Net.Cache;
 using System.Net.Sockets;
 using System.Runtime.Remoting.Messaging;
@@ -46,12 +47,8 @@ using System.Threading;
 
 namespace System.Net 
 {
-#if MOONLIGHT
-       internal class HttpWebRequest : WebRequest, ISerializable {
-#else
        [Serializable]
        public class HttpWebRequest : WebRequest, ISerializable {
-#endif
                Uri requestUri;
                Uri actualUri;
                bool hostChanged;
@@ -194,6 +191,13 @@ namespace System.Net
                        get { return allowBuffering; }
                        set { allowBuffering = value; }
                }
+               
+#if NET_4_5
+               public virtual bool AllowReadStreamBuffering {
+                       get { return allowBuffering; }
+                       set { allowBuffering = value; }
+               }
+#endif
 
                static Exception GetMustImplement ()
                {
@@ -291,6 +295,9 @@ namespace System.Net
                        set { continueDelegate = value; }
                }
                
+#if NET_4_5
+               virtual
+#endif
                public CookieContainer CookieContainer {
                        get { return cookieContainer; }
                        set { cookieContainer = value; }
@@ -309,10 +316,15 @@ namespace System.Net
                                return DateTime.ParseExact (date, "r", CultureInfo.InvariantCulture).ToLocalTime ();
                        }
                        set {
-                               webHeaders.RemoveAndAdd ("Date", value.ToUniversalTime ().ToString ("r", CultureInfo.InvariantCulture));
+                               if (value.Equals (DateTime.MinValue))
+                                       webHeaders.RemoveInternal ("Date");
+                               else
+                                       webHeaders.RemoveAndAdd ("Date", value.ToUniversalTime ().ToString ("r", CultureInfo.InvariantCulture));
                        }
                }
 #endif
+
+#if !NET_2_1
                [MonoTODO]
                public static new RequestCachePolicy DefaultCachePolicy
                {
@@ -323,6 +335,7 @@ namespace System.Net
                                throw GetMustImplement ();
                        }
                }
+#endif
                
                [MonoTODO]
                public static int DefaultMaximumErrorResponseLength
@@ -355,6 +368,9 @@ namespace System.Net
                        }
                }
                
+#if NET_4_5
+               virtual
+#endif
                public bool HaveResponse {
                        get { return haveResponse; }
                }
@@ -396,9 +412,6 @@ namespace System.Net
 
                static bool CheckValidHost (string scheme, string val)
                {
-                       if (val == null)
-                               throw new ArgumentNullException ("value");
-
                        if (val.Length == 0)
                                return false;
 
@@ -409,6 +422,10 @@ namespace System.Net
                        if (idx >= 0)
                                return false;
 
+                       IPAddress ipaddr;
+                       if (IPAddress.TryParse (val, out ipaddr))
+                               return true;
+
                        string u = scheme + "://" + val + "/";
                        return Uri.IsWellFormedUriString (u, UriKind.Absolute);
                }
@@ -477,6 +494,14 @@ namespace System.Net
                        }
                }
                
+#if NET_4_5
+               [MonoTODO]
+               public int ContinueTimeout {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+#endif
+               
                public string MediaType {
                        get { return mediaType; }
                        set { 
@@ -560,9 +585,9 @@ namespace System.Net
                internal ServicePoint ServicePointNoLock {
                        get { return servicePoint; }
                }
-#if NET_4_5 || MOBILE
+#if NET_4_0
                [MonoTODO ("for portable library support")]
-               public bool SupportsCookieContainer { 
+               public virtual bool SupportsCookieContainer { 
                        get {
                                throw new NotImplementedException ();
                        }
@@ -765,6 +790,9 @@ namespace System.Net
 
                        lock (locker)
                        {
+                               if (getResponseCalled)
+                                       throw new InvalidOperationException ("The operation cannot be performed once the request has been submitted.");
+
                                if (asyncWrite != null) {
                                        throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
                                                                "method while a previous call is still in progress.");
@@ -832,10 +860,10 @@ namespace System.Net
                        if (writeStream == null || writeStream.RequestWritten || !InternalAllowBuffering)
                                return;
 #if NET_4_0
-                       if (contentLength < 0 && writeStream.CanWrite == true && writeStream.WriteBufferLength <= 0)
+                       if (contentLength < 0 && writeStream.CanWrite == true && writeStream.WriteBufferLength < 0)
                                return;
 
-                       if (contentLength < 0 && writeStream.WriteBufferLength > 0)
+                       if (contentLength < 0 && writeStream.WriteBufferLength >= 0)
                                InternalContentLength = writeStream.WriteBufferLength;
 #else
                        if (contentLength < 0 && writeStream.CanWrite == true)
@@ -923,6 +951,14 @@ namespace System.Net
 
                        return result.Response;
                }
+               
+#if NET_3_5
+               public Stream EndGetRequestStream (IAsyncResult asyncResult, out TransportContext transportContext)
+               {
+                       transportContext = null;
+                       return EndGetRequestStream (asyncResult);
+               }
+#endif
 
                public override WebResponse GetResponse()
                {
@@ -1044,29 +1080,19 @@ namespace System.Net
                        redirects++;
                        Exception e = null;
                        string uriString = null;
-
                        switch (code) {
                        case HttpStatusCode.Ambiguous: // 300
                                e = new WebException ("Ambiguous redirect.");
                                break;
                        case HttpStatusCode.MovedPermanently: // 301
                        case HttpStatusCode.Redirect: // 302
-                       case HttpStatusCode.TemporaryRedirect: // 307
-                               /* MS follows the redirect for POST too
-                               if (method != "GET" && method != "HEAD") // 10.3
-                                       return false;
-                               */
-
-                               contentLength = -1;
-                               bodyBufferLength = 0;
-                               bodyBuffer = null;
-                               if (code != HttpStatusCode.TemporaryRedirect)
+                               if (method == "POST")
                                        method = "GET";
-                               uriString = webResponse.Headers ["Location"];
+                               break;
+                       case HttpStatusCode.TemporaryRedirect: // 307
                                break;
                        case HttpStatusCode.SeeOther: //303
                                method = "GET";
-                               uriString = webResponse.Headers ["Location"];
                                break;
                        case HttpStatusCode.NotModified: // 304
                                return false;
@@ -1082,6 +1108,11 @@ namespace System.Net
                        if (e != null)
                                throw e;
 
+                       //contentLength = -1;
+                       //bodyBufferLength = 0;
+                       //bodyBuffer = null;
+                       uriString = webResponse.Headers ["Location"];
+
                        if (uriString == null)
                                throw new WebException ("No Location header found for " + (int) code,
                                                        WebExceptionStatus.ProtocolError);
@@ -1136,7 +1167,9 @@ namespace System.Net
                        bool spoint10 = (proto_version == null || proto_version == HttpVersion.Version10);
 
                        if (keepAlive && (version == HttpVersion.Version10 || spoint10)) {
-                               webHeaders.RemoveAndAdd (connectionHeader, "keep-alive");
+                               if (webHeaders[connectionHeader] == null
+                                   || webHeaders[connectionHeader].IndexOf ("keep-alive", StringComparison.OrdinalIgnoreCase) == -1)
+                                       webHeaders.RemoveAndAdd (connectionHeader, "keep-alive");
                        } else if (!keepAlive && version == HttpVersion.Version11) {
                                webHeaders.RemoveAndAdd (connectionHeader, "close");
                        }
@@ -1145,7 +1178,9 @@ namespace System.Net
                        if (cookieContainer != null) {
                                string cookieHeader = cookieContainer.GetCookieHeader (actualUri);
                                if (cookieHeader != "")
-                                       webHeaders.SetInternal ("Cookie", cookieHeader);
+                                       webHeaders.RemoveAndAdd ("Cookie", cookieHeader);
+                               else
+                                       webHeaders.RemoveInternal ("Cookie");
                        }
 
                        string accept_encoding = null;
@@ -1457,7 +1492,7 @@ namespace System.Net
                        if (isProxy && (proxy == null || proxy.Credentials == null))
                                return false;
 
-                       string [] authHeaders = response.Headers.GetValues ( (isProxy) ? "Proxy-Authenticate" : "WWW-Authenticate");
+                       string [] authHeaders = response.Headers.GetValues_internal ( (isProxy) ? "Proxy-Authenticate" : "WWW-Authenticate", false);
                        if (authHeaders == null || authHeaders.Length == 0)
                                return false;
 
@@ -1576,6 +1611,13 @@ namespace System.Net
 
                        throw throwMe;
                }
+
+               internal bool ReuseConnection {
+                       get;
+                       set;
+               }
+
+               internal WebConnection StoredConnection;
        }
 }