New test.
[mono.git] / mcs / class / System / System.Net / HttpWebRequest.cs
index 109533d06a970f9c5646d7713b2916f0a08522d7..9783525f71e150c29619d2636226f30f5cc48630 100644 (file)
@@ -91,6 +91,7 @@ namespace System.Net
                int bodyBufferLength;
                bool getResponseCalled;
                Exception saved_exc;
+               object locker = new object ();
 #if NET_1_1
                int maxResponseHeadersLength;
                static int defaultMaxResponseHeadersLength;
@@ -473,11 +474,12 @@ namespace System.Net
                }
 
 #if NET_1_1
+               bool unsafe_auth_blah;
                [MonoTODO]
                public bool UnsafeAuthenticatedConnectionSharing
                {
-                       get { throw new NotImplementedException (); }
-                       set { throw new NotImplementedException (); }
+                       get { return unsafe_auth_blah; }
+                       set { unsafe_auth_blah = value; }
                }
 #endif
 
@@ -502,10 +504,7 @@ namespace System.Net
                
                internal ServicePoint GetServicePoint ()
                {
-                       if (!hostChanged && servicePoint != null)
-                               return servicePoint;
-
-                       lock (this) {
+                       lock (locker) {
                                if (hostChanged || servicePoint == null) {
                                        servicePoint = ServicePointManager.FindServicePoint (actualUri, proxy);
                                        hostChanged = false;
@@ -554,11 +553,12 @@ namespace System.Net
                                throw new InvalidOperationException ("rangeSpecifier");
                        webHeaders.RemoveAndAdd ("Range", value + from + "-" + to);     
                }
-               
+#if !NET_2_0
                public override int GetHashCode ()
                {
                        return base.GetHashCode ();
                }
+#endif
                
                void CommonChecks (bool putpost)
                {
@@ -584,7 +584,7 @@ namespace System.Net
 
                        CommonChecks (send);
                        
-                       lock (this)
+                       lock (locker)
                        {
                                if (asyncWrite != null) {
                                        throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
@@ -643,7 +643,18 @@ namespace System.Net
 
                        return EndGetRequestStream (asyncResult);
                }
-               
+
+               void CheckIfForceWrite ()
+               {
+                       if (writeStream == null || contentLength < 0 || !InternalAllowBuffering)
+                               return;
+
+                       // This will write the POST/PUT if the write stream already has the expected
+                       // amount of bytes in it (ContentLength) (bug #77753).
+                       if (writeStream.WriteBufferLength == contentLength)
+                               writeStream.WriteRequest ();
+               }
+
                public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
                {
                        bool send = (method == "PUT" || method == "POST");
@@ -661,6 +672,7 @@ namespace System.Net
                                                        "method while a previous call is still in progress.");
                        }
 
+                       CheckIfForceWrite ();
                        asyncRead = new WebAsyncResult (this, callback, state);
                        initialMethod = method;
                        if (haveResponse) {
@@ -807,8 +819,10 @@ namespace System.Net
                        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;
+                               */
 
                                uriString = webResponse.Headers ["Location"];
                                break;
@@ -852,7 +866,8 @@ namespace System.Net
                {
                        bool continue100 = false;
                        if (contentLength != -1) {
-                               continue100 = true;
+                               if (contentLength > 0)
+                                       continue100 = true;
                                webHeaders.SetInternal ("Content-Length", contentLength.ToString ());
                                webHeaders.RemoveInternal ("Transfer-Encoding");
                        } else if (sendChunked) {
@@ -966,7 +981,7 @@ namespace System.Net
                                contentLength = bodyBufferLength;
                                writeStream.SendChunked = false;
                        }
-                       
+
                        SendRequestHeaders ();
 
                        haveRequest = true;
@@ -1015,7 +1030,8 @@ namespace System.Net
                void CheckSendError (WebConnectionData data)
                {
                        // Got here, but no one called GetResponse
-                       if (data.StatusCode < 400)
+                       int status = data.StatusCode;
+                       if (status < 400 || status == 401 || status == 407)
                                return;
 
                        if (writeStream != null && asyncRead == null && !writeStream.CompleteRequestWritten) {
@@ -1045,7 +1061,7 @@ namespace System.Net
                        }
 
                        if (wexc == null && (method == "POST" || method == "PUT")) {
-                               lock (this) {
+                               lock (locker) {
                                        CheckSendError (data);
                                        if (saved_exc != null)
                                                wexc = (WebException) saved_exc;
@@ -1127,9 +1143,9 @@ namespace System.Net
                        WebExceptionStatus protoError = WebExceptionStatus.ProtocolError;
                        HttpStatusCode code = 0;
                        if (throwMe == null && webResponse != null) {
-                               code  = webResponse.StatusCode;
+                               code = webResponse.StatusCode;
                                if (!authCompleted && ((code == HttpStatusCode.Unauthorized && credentials != null) ||
-                                                       code == HttpStatusCode.ProxyAuthenticationRequired)) {
+                                    (ProxyQuery && code == HttpStatusCode.ProxyAuthenticationRequired))) {
                                        if (!usedPreAuth && CheckAuthorization (webResponse, code)) {
                                                // Keep the written body, so it can be rewritten in the retry
                                                if (InternalAllowBuffering) {
@@ -1172,8 +1188,13 @@ namespace System.Net
                        if (throwMe == null) {
                                bool b = false;
                                int c = (int) code;
-                               if (allowAutoRedirect && c >= 300)
+                               if (allowAutoRedirect && c >= 300) {
+                                       if (InternalAllowBuffering && writeStream.WriteBufferLength > 0) {
+                                               bodyBuffer = writeStream.WriteBuffer;
+                                               bodyBufferLength = writeStream.WriteBufferLength;
+                                       }
                                        b = Redirect (result, code);
+                               }
 
                                if (resp != null && c >= 300 && c != 304)
                                        resp.ReadAll ();