[System*] Throw a PlatformNotSupported exception when using the networking stack...
[mono.git] / mcs / class / System / Test / System.Net / HttpWebRequestTest.cs
1 //
2 // HttpWebRequestTest.cs - NUnit Test Cases for System.Net.HttpWebRequest
3 //
4 // Authors:
5 //   Lawrence Pit (loz@cable.a2000.nl)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //   Andres G. Aragoneses (andres@7digital.com)
9 //   Bogdanov Kirill (bogdanov@macroscop.com)
10 //
11 // (C) 2003 Martin Willemoes Hansen
12 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com
13 // Copyright (c) 2013 7digital Media Ltd (http://www.7digital.com)
14 //
15
16 using NUnit.Framework;
17 using System;
18 using System.Collections;
19 using System.Collections.Specialized;
20 using System.Globalization;
21 using System.IO;
22 using System.Net;
23 using System.Net.Sockets;
24 using System.Security.Cryptography;
25 using System.Security.Cryptography.X509Certificates;
26 using System.Text;
27 using System.Threading;
28 using System.Reflection;
29 using Mono.Security.Authenticode;
30 #if !MOBILE
31 using Mono.Security.Protocol.Tls;
32 #endif
33
34 using MonoTests.Helpers;
35
36 namespace MonoTests.System.Net
37 {
38         [TestFixture]
39         public class HttpWebRequestTest
40         {
41                 private Random rand = new Random ();
42                 private byte [] data64KB = new byte [64 * 1024];
43
44                 [TestFixtureSetUp]
45                 public void Setup ()
46                 {
47 #if !FEATURE_NO_BSD_SOCKETS
48                                 ServicePointManager.Expect100Continue = false;
49 #endif
50                                 rand.NextBytes (data64KB);
51                 }
52
53                 [Test]
54 #if FEATURE_NO_BSD_SOCKETS
55                 [ExpectedException (typeof (PlatformNotSupportedException))]
56 #endif
57                 public void Proxy_Null ()
58                 {
59                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
60                         Assert.IsNotNull (req.Proxy, "#1");
61                         req.Proxy = null;
62                         Assert.IsNull (req.Proxy, "#2");
63                 }
64
65                 [Test]
66                 [Category("InetAccess")]
67 #if FEATURE_NO_BSD_SOCKETS
68                 [ExpectedException (typeof (PlatformNotSupportedException))]
69 #endif
70                 public void Sync ()
71                 {
72                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
73                         Assert.IsNotNull (req.IfModifiedSince, "req:If Modified Since: ");
74
75                         req.UserAgent = "MonoClient v1.0";
76                         Assert.AreEqual ("User-Agent", req.Headers.GetKey (0), "#A1");
77                         Assert.AreEqual ("MonoClient v1.0", req.Headers.Get (0), "#A2");
78
79                         HttpWebResponse res = (HttpWebResponse) req.GetResponse ();
80                         Assert.AreEqual ("OK", res.StatusCode.ToString (), "#B1");
81                         Assert.AreEqual ("OK", res.StatusDescription, "#B2");
82
83                         Assert.IsTrue (res.Headers.Get ("Content-Type").StartsWith ("text/html; charset=", StringComparison.OrdinalIgnoreCase), "#C1");
84                         Assert.IsNotNull (res.LastModified, "#C2");
85                         Assert.AreEqual (0, res.Cookies.Count, "#C3");
86
87                         res.Close ();
88                 }
89
90                 [Test]
91 #if FEATURE_NO_BSD_SOCKETS
92                 [ExpectedException (typeof (PlatformNotSupportedException))]
93 #endif
94                 public void AddRange ()
95                 {
96                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
97                         req.AddRange (10);
98                         req.AddRange (50, 90);
99                         req.AddRange ("bytes", 100); 
100                         req.AddRange ("bytes", 100, 120);
101                         Assert.AreEqual ("bytes=10-,50-90,100-,100-120", req.Headers ["Range"], "#1");
102                         try {
103                                 req.AddRange ("bits", 2000);
104                                 Assert.Fail ("#2");
105                         } catch (InvalidOperationException) {}
106                 }
107
108                 [Test] // bug #471782
109 #if FEATURE_NO_BSD_SOCKETS
110                 [ExpectedException (typeof (PlatformNotSupportedException))]
111 #endif
112                 public void CloseRequestStreamAfterReadingResponse ()
113                 {
114                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
115                         string url = "http://" + ep.ToString () + "/test/";
116
117                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
118                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
119                                 req.Method = "POST";
120                                 req.Timeout = 2000;
121                                 req.ReadWriteTimeout = 2000;
122
123                                 byte [] data = new byte [128];
124                                 req.ContentLength = data.Length;
125
126                                 Stream rs = req.GetRequestStream ();
127                                 rs.Write (data, 0, data.Length);
128                                 rs.Flush ();
129
130                                 HttpWebResponse response = (HttpWebResponse) req.GetResponse ();
131                                 response.Close ();
132
133                                 rs.Close ();
134                         }
135                 }
136
137                 [Test]
138                 //[Category("InetAccess")]
139                 [Category ("NotWorking")] // Disabled until a server that meets requirements is found
140                 public void Cookies1 ()
141                 {
142                         // The purpose of this test is to ensure that the cookies we get from a request
143                         // are stored in both, the CookieCollection in HttpWebResponse and the CookieContainer
144                         // in HttpWebRequest.
145                         // If this URL stops sending *one* and only one cookie, replace it.
146                         string url = "http://xamarin.com";
147                         CookieContainer cookies = new CookieContainer ();
148                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
149                         req.KeepAlive = false;
150                         req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv; 1.7.6) Gecko/20050317 Firefox/1.0.2";
151                         req.CookieContainer = cookies;
152                         Assert.AreEqual (0, cookies.Count, "#01");
153                         using (HttpWebResponse res = (HttpWebResponse) req.GetResponse()) {
154                                 CookieCollection coll = req.CookieContainer.GetCookies (new Uri (url));
155                                 Assert.AreEqual (1, coll.Count, "#02");
156                                 Assert.AreEqual (1, res.Cookies.Count, "#03");
157                                 Cookie one = coll [0];
158                                 Cookie two = res.Cookies [0];
159                                 Assert.AreEqual (true, object.ReferenceEquals (one, two), "#04");
160                         }
161                 }
162
163 #if !MOBILE
164                 [Test]
165                 [Ignore ("Fails on MS.NET")]
166                 public void SslClientBlock ()
167                 {
168                         // This tests that the write request/initread/write body sequence does not hang
169                         // when using SSL.
170                         // If there's a regression for this, the test will hang.
171                         ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
172                         try {
173                                 SslHttpServer server = new SslHttpServer ();
174                                 server.Start ();
175
176                                 string url = String.Format ("https://{0}:{1}/nothing.html", server.IPAddress, server.Port);
177                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
178                                 request.Method = "POST";
179                                 Stream stream = request.GetRequestStream ();
180                                 byte [] bytes = new byte [100];
181                                 stream.Write (bytes, 0, bytes.Length);
182                                 stream.Close ();
183                                 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
184                                 Assert.AreEqual (200, (int) resp.StatusCode, "StatusCode");
185                                 StreamReader sr = new StreamReader (resp.GetResponseStream (), Encoding.UTF8);
186                                 sr.ReadToEnd ();
187                                 sr.Close ();
188                                 resp.Close ();
189                                 server.Stop ();
190                                 if (server.Error != null)
191                                         throw server.Error;
192                         } finally {
193                                 ServicePointManager.CertificatePolicy = null;
194                         }
195                 }
196 #endif
197                 [Test]
198 #if FEATURE_NO_BSD_SOCKETS
199                 [ExpectedException (typeof (PlatformNotSupportedException))]
200 #endif
201                 public void Missing_ContentEncoding ()
202                 {
203                         ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
204                         try {
205                                 BadChunkedServer server = new BadChunkedServer ();
206                                 server.Start ();
207
208                                 string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
209                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
210                                 request.Method = "GET";
211                                 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
212                                 Assert.AreEqual ("", resp.ContentEncoding);
213                                 resp.Close ();
214                                 server.Stop ();
215                                 if (server.Error != null)
216                                         throw server.Error;
217                         } finally {
218                                 ServicePointManager.CertificatePolicy = null;
219                         }
220                 }
221
222                 [Test]
223 #if FEATURE_NO_BSD_SOCKETS
224                 [ExpectedException (typeof (PlatformNotSupportedException))]
225 #endif
226                 public void BadServer_ChunkedClose ()
227                 {
228                         // The server will send a chunked response without a 'last-chunked' mark
229                         // and then shutdown the socket for sending.
230                         BadChunkedServer server = new BadChunkedServer ();
231                         server.Start ();
232                         string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
233                         HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
234                         HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
235                         string x = null;
236                         try {
237                                 byte [] bytes = new byte [32];
238                                 // Using StreamReader+UTF8Encoding here fails on MS runtime
239                                 Stream stream = resp.GetResponseStream ();
240                                 int nread = stream.Read (bytes, 0, 32);
241                                 Assert.AreEqual (16, nread, "#01");
242                                 x = Encoding.ASCII.GetString (bytes, 0, 16);
243                         } finally {
244                                 resp.Close ();
245                                 server.Stop ();
246                         }
247
248                         if (server.Error != null)
249                                 throw server.Error;
250
251                         Assert.AreEqual ("1234567890123456", x);
252                 }
253
254                 [Test]
255                 [Ignore ("This test asserts that our code violates RFC 2616")]
256                 public void MethodCase ()
257                 {
258                         ListDictionary methods = new ListDictionary ();
259                         methods.Add ("post", "POST");
260                         methods.Add ("puT", "PUT");
261                         methods.Add ("POST", "POST");
262                         methods.Add ("whatever", "whatever");
263                         methods.Add ("PUT", "PUT");
264
265                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
266                         string url = "http://" + ep.ToString () + "/test/";
267
268                         foreach (DictionaryEntry de in methods) {
269                                 using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
270                                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
271                                         req.Method = (string) de.Key;
272                                         req.Timeout = 2000;
273                                         req.ReadWriteTimeout = 2000;
274                                         req.KeepAlive = false;
275                                         Stream rs = req.GetRequestStream ();
276                                         rs.Close ();
277                                         using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
278                                                 StreamReader sr = new StreamReader (resp.GetResponseStream (),
279                                                         Encoding.UTF8);
280                                                 string line = sr.ReadLine ();
281                                                 sr.Close ();
282                                                 Assert.AreEqual (((string) de.Value) + " /test/ HTTP/1.1",
283                                                         line, req.Method);
284                                                 resp.Close ();
285                                         }
286                                 }
287                         }
288                 }
289
290                 [Test]
291 #if FEATURE_NO_BSD_SOCKETS
292                 [ExpectedException (typeof (PlatformNotSupportedException))]
293 #endif
294                 public void BeginGetRequestStream_Body_NotAllowed ()
295                 {
296                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
297                         string url = "http://" + ep.ToString () + "/test/";
298
299                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
300                                 HttpWebRequest request;
301
302                                 request = (HttpWebRequest) WebRequest.Create (url);
303                                 request.Method = "GET";
304
305                                 try {
306                                         request.BeginGetRequestStream (null, null);
307                                         Assert.Fail ("#A1");
308                                 } catch (ProtocolViolationException ex) {
309                                         // Cannot send a content-body with this
310                                         // verb-type
311                                         Assert.IsNull (ex.InnerException, "#A2");
312                                         Assert.IsNotNull (ex.Message, "#A3");
313                                 }
314
315                                 request = (HttpWebRequest) WebRequest.Create (url);
316                                 request.Method = "HEAD";
317
318                                 try {
319                                         request.BeginGetRequestStream (null, null);
320                                         Assert.Fail ("#B1");
321                                 } catch (ProtocolViolationException ex) {
322                                         // Cannot send a content-body with this
323                                         // verb-type
324                                         Assert.IsNull (ex.InnerException, "#B2");
325                                         Assert.IsNotNull (ex.Message, "#B3");
326                                 }
327                         }
328                 }
329
330                 [Test] // bug #465613
331 #if FEATURE_NO_BSD_SOCKETS
332                 [ExpectedException (typeof (PlatformNotSupportedException))]
333 #endif
334                 public void BeginGetRequestStream_NoBuffering ()
335                 {
336                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
337                         string url = "http://" + ep.ToString () + "/test/";
338
339                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
340                                 HttpWebRequest req;
341                                 Stream rs;
342                                 IAsyncResult ar;
343
344                                 req = (HttpWebRequest) WebRequest.Create (url);
345                                 req.Method = "POST";
346                                 req.SendChunked = false;
347                                 req.KeepAlive = false;
348                                 req.AllowWriteStreamBuffering = false;
349
350                                 ar = req.BeginGetRequestStream (null, null);
351                                 rs = req.EndGetRequestStream (ar);
352                                 rs.Close ();
353
354                                 req = (HttpWebRequest) WebRequest.Create (url);
355                                 req.Method = "POST";
356                                 req.SendChunked = false;
357                                 req.KeepAlive = true;
358                                 req.AllowWriteStreamBuffering = false;
359
360                                 try {
361                                         req.BeginGetRequestStream (null, null);
362                                         Assert.Fail ("#A1");
363                                 } catch (ProtocolViolationException ex) {
364                                         // When performing a write operation with
365                                         // AllowWriteStreamBuffering set to false,
366                                         // you must either set ContentLength to a
367                                         // non-negative number or set SendChunked
368                                         // to true
369                                         Assert.IsNull (ex.InnerException, "#A2");
370                                         Assert.IsNotNull (ex.Message, "#A3");
371                                 }
372
373                                 req = (HttpWebRequest) WebRequest.Create (url);
374                                 req.Method = "POST";
375                                 req.SendChunked = false;
376                                 req.KeepAlive = true;
377                                 req.AllowWriteStreamBuffering = false;
378                                 req.ContentLength = 0;
379
380                                 ar = req.BeginGetRequestStream (null, null);
381                                 rs = req.EndGetRequestStream (ar);
382                                 rs.Close ();
383                         }
384                 }
385
386                 [Test] // bug #508027
387                 [Category ("NotWorking")] // #5842
388                 public void BeginGetResponse ()
389                 {
390                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
391                         string url = "http://" + ep.ToString () + "/test/";
392
393                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
394                                 HttpWebRequest req;
395
396                                 req = (HttpWebRequest) WebRequest.Create (url);
397                                 req.Timeout = 5000;
398                                 req.Method = "POST";
399                                 req.SendChunked = false;
400                                 req.KeepAlive = false;
401                                 req.AllowWriteStreamBuffering = false;
402                                 req.BeginGetResponse (null, null);
403                                 req.Abort ();
404
405                                 req = (HttpWebRequest) WebRequest.Create (url);
406                                 req.Timeout = 5000;
407                                 req.Method = "POST";
408                                 req.SendChunked = true;
409                                 req.KeepAlive = false;
410                                 req.AllowWriteStreamBuffering = false;
411                                 req.GetRequestStream ().WriteByte (1);
412                                 req.BeginGetResponse (null, null);
413                                 req.Abort ();
414
415                                 req = (HttpWebRequest) WebRequest.Create (url);
416                                 req.Timeout = 5000;
417                                 req.Method = "POST";
418                                 req.ContentLength = 5;
419                                 req.SendChunked = false;
420                                 req.KeepAlive = false;
421                                 req.AllowWriteStreamBuffering = false;
422                                 req.GetRequestStream ().WriteByte (5);
423                                 req.BeginGetResponse (null, null);
424                                 req.Abort ();
425
426                                 req = (HttpWebRequest) WebRequest.Create (url);
427                                 req.Timeout = 5000;
428                                 req.Method = "POST";
429                                 req.SendChunked = false;
430                                 req.KeepAlive = true;
431                                 req.AllowWriteStreamBuffering = false;
432
433                                 req.BeginGetResponse (null, null);
434                                 req.Abort ();
435
436                                 req = (HttpWebRequest) WebRequest.Create (url);
437                                 req.Timeout = 5000;
438                                 req.Method = "POST";
439                                 req.SendChunked = false;
440                                 req.KeepAlive = false;
441                                 req.AllowWriteStreamBuffering = false;
442                                 req.ContentLength = 5;
443                                 req.BeginGetResponse (null, null);
444                                 req.Abort ();
445
446                                 req = (HttpWebRequest) WebRequest.Create (url);
447                                 req.Timeout = 5000;
448                                 req.Method = "POST";
449                                 req.SendChunked = false;
450                                 req.KeepAlive = true;
451                                 req.AllowWriteStreamBuffering = false;
452                                 req.ContentLength = 5;
453                                 req.BeginGetResponse (null, null);
454                                 req.Abort ();
455
456                                 req = (HttpWebRequest) WebRequest.Create (url);
457                                 req.Timeout = 5000;
458                                 req.Method = "GET";
459                                 req.SendChunked = true;
460
461                                 req.BeginGetResponse (null, null);
462                                 req.Abort ();
463
464                                 req = (HttpWebRequest) WebRequest.Create (url);
465                                 req.Timeout = 5000;
466                                 req.Method = "GET";
467                                 req.ContentLength = 5;
468
469                                 req.BeginGetResponse (null, null);
470                                 req.Abort ();
471
472                                 req = (HttpWebRequest) WebRequest.Create (url);
473                                 req.Timeout = 5000;
474                                 req.Method = "GET";
475                                 req.ContentLength = 0;
476
477                                 req.BeginGetResponse (null, null);
478                                 req.Abort ();
479                         }
480                 }
481
482                 [Test] // bug #511851
483 #if FEATURE_NO_BSD_SOCKETS
484                 [ExpectedException (typeof (PlatformNotSupportedException))]
485 #endif
486                 public void BeginGetRequestStream_Request_Aborted ()
487                 {
488                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
489                         string url = "http://" + ep.ToString () + "/test/";
490
491                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
492                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
493                                 req.Method = "POST";
494                                 req.Abort ();
495
496                                 try {
497                                         req.BeginGetRequestStream (null, null);
498                                         Assert.Fail ("#1");
499                                 } catch (WebException ex) {
500                                         // The request was aborted: The request was canceled
501                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
502                                         Assert.IsNull (ex.InnerException, "#3");
503                                         Assert.IsNotNull (ex.Message, "#4");
504                                         Assert.IsNull (ex.Response, "#5");
505                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
506                                 }
507                         }
508                 }
509
510                 [Test] // bug #511851
511 #if FEATURE_NO_BSD_SOCKETS
512                 [ExpectedException (typeof (PlatformNotSupportedException))]
513 #endif
514                 public void BeginGetResponse_Request_Aborted ()
515                 {
516                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
517                         string url = "http://" + ep.ToString () + "/test/";
518
519                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
520                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
521                                 req.Method = "POST";
522                                 req.Abort ();
523
524                                 try {
525                                         req.BeginGetResponse (null, null);
526                                         Assert.Fail ("#1");
527                                 } catch (WebException ex) {
528                                         // The request was aborted: The request was canceled
529                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
530                                         Assert.IsNull (ex.InnerException, "#3");
531                                         Assert.IsNotNull (ex.Message, "#4");
532                                         Assert.IsNull (ex.Response, "#5");
533                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
534                                 }
535                         }
536                 }
537
538                 [Test]
539 #if FEATURE_NO_BSD_SOCKETS
540                 [ExpectedException (typeof (PlatformNotSupportedException))]
541 #endif
542                 public void EndGetRequestStream_AsyncResult_Null ()
543                 {
544                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
545                         string url = "http://" + ep.ToString () + "/test/";
546
547                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
548                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
549                                 req.Method = "POST";
550                                 req.BeginGetRequestStream (null, null);
551
552                                 try {
553                                         req.EndGetRequestStream (null);
554                                         Assert.Fail ("#1");
555                                 } catch (ArgumentNullException ex) {
556                                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
557                                         Assert.IsNull (ex.InnerException, "#3");
558                                         Assert.IsNotNull (ex.Message, "#4");
559                                         Assert.AreEqual ("asyncResult", ex.ParamName, "#5");
560                                 } finally {
561                                         req.Abort ();
562                                 }
563                         }
564                 }
565
566                 [Test]
567                 [Category ("NotWorking")] // do not get consistent result on MS
568                 public void EndGetRequestStream_Request_Aborted ()
569                 {
570                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
571                         string url = "http://" + ep.ToString () + "/test/";
572
573                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
574                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
575                                 req.Method = "POST";
576                                 IAsyncResult ar = req.BeginGetRequestStream (null, null);
577                                 req.Abort ();
578                                 Thread.Sleep (500);
579
580                                 try {
581                                         req.EndGetRequestStream (ar);
582                                         Assert.Fail ("#1");
583                                 } catch (WebException ex) {
584                                         // The request was aborted: The request was canceled
585                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
586                                         Assert.IsNull (ex.InnerException, "#3");
587                                         Assert.IsNotNull (ex.Message, "#4");
588                                         Assert.IsNull (ex.Response, "#5");
589                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
590                                 }
591                         }
592                 }
593
594                 [Test] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=471522
595                 [Category ("NotWorking")]
596                 public void EndGetResponse_AsyncResult_Invalid ()
597                 {
598                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
599                         string url = "http://" + ep.ToString () + "/test/";
600
601                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
602                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
603                                 req.Method = "POST";
604                                 req.Timeout = 2000;
605                                 req.ReadWriteTimeout = 2000;
606                                 IAsyncResult ar = req.BeginGetRequestStream (null, null);
607
608                                 // AsyncResult was not returned from call to BeginGetResponse
609                                 try {
610                                         req.EndGetResponse (ar);
611                                         Assert.Fail ();
612                                 } catch (InvalidCastException) {
613                                 } finally {
614                                         req.Abort ();
615                                 }
616                         }
617                 }
618
619                 [Test]
620 #if FEATURE_NO_BSD_SOCKETS
621                 [ExpectedException (typeof (PlatformNotSupportedException))]
622 #endif
623                 public void EndGetResponse_AsyncResult_Null ()
624                 {
625                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
626                         string url = "http://" + ep.ToString () + "/test/";
627
628                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
629                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
630                                 req.Timeout = 2000;
631                                 req.ReadWriteTimeout = 2000;
632                                 req.Method = "POST";
633                                 IAsyncResult ar = req.BeginGetResponse (null, null);
634
635                                 try {
636                                         req.EndGetResponse (null);
637                                         Assert.Fail ("#1");
638                                 } catch (ArgumentNullException ex) {
639                                         Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
640                                         Assert.IsNull (ex.InnerException, "#3");
641                                         Assert.IsNotNull (ex.Message, "#4");
642                                         Assert.AreEqual ("asyncResult", ex.ParamName, "#5");
643                                 } finally {
644                                         req.Abort ();
645                                         /*
646                                         using (HttpWebResponse resp = (HttpWebResponse) req.EndGetResponse (ar)) {
647                                                 resp.Close ();
648                                         }*/
649                                 }
650                         }
651                 }
652
653                 [Test] // bug #429200
654 #if FEATURE_NO_BSD_SOCKETS
655                 [ExpectedException (typeof (PlatformNotSupportedException))]
656 #endif
657                 public void GetRequestStream ()
658                 {
659                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
660                         string url = "http://" + ep.ToString () + "/test/";
661
662                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
663                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
664                                 req.Method = "POST";
665                                 req.Timeout = 2000;
666                                 req.ReadWriteTimeout = 2000;
667
668                                 Stream rs1 = req.GetRequestStream ();
669                                 Stream rs2 = req.GetRequestStream ();
670
671                                 Assert.IsNotNull (rs1, "#1");
672                                 Assert.AreSame (rs1, rs2, "#2");
673
674                                 rs1.Close ();
675                         }
676                 }
677
678                 [Test] // bug #511851
679 #if FEATURE_NO_BSD_SOCKETS
680                 [ExpectedException (typeof (PlatformNotSupportedException))]
681 #endif
682                 public void GetRequestStream_Request_Aborted ()
683                 {
684                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
685                         string url = "http://" + ep.ToString () + "/test/";
686
687                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
688                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
689                                 req.Method = "POST";
690                                 req.Abort ();
691
692                                 try {
693                                         req.GetRequestStream ();
694                                         Assert.Fail ("#1");
695                                 } catch (WebException ex) {
696                                         // The request was aborted: The request was canceled
697                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
698                                         Assert.IsNull (ex.InnerException, "#3");
699                                         Assert.IsNotNull (ex.Message, "#4");
700                                         Assert.IsNull (ex.Response, "#5");
701                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
702                                 }
703                         }
704                 }
705
706                 [Test] // bug #510661
707                 [Category ("NotWorking")] // #5842
708                 public void GetRequestStream_Close_NotAllBytesWritten ()
709                 {
710                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
711                         string url = "http://" + ep.ToString () + "/test/";
712
713                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
714                                 HttpWebRequest req;
715                                 Stream rs;
716
717                                 req = (HttpWebRequest) WebRequest.Create (url);
718                                 req.Method = "POST";
719                                 req.ContentLength = 2;
720                                 rs = req.GetRequestStream ();
721                                 try {
722                                         rs.Close ();
723                                         Assert.Fail ("#A1");
724                                 } catch (WebException ex) {
725                                         // The request was aborted: The request was canceled
726                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
727                                         Assert.IsNotNull (ex.Message, "#A3");
728                                         Assert.IsNull (ex.Response, "#A4");
729                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#A5");
730
731                                         // Cannot close stream until all bytes are written
732                                         Exception inner = ex.InnerException;
733                                         Assert.IsNotNull (inner, "#A6");
734                                         Assert.AreEqual (typeof (IOException), inner.GetType (), "#A7");
735                                         Assert.IsNull (inner.InnerException, "#A8");
736                                         Assert.IsNotNull (inner.Message, "#A9");
737                                 }
738
739                                 req = (HttpWebRequest) WebRequest.Create (url);
740                                 req.Method = "POST";
741                                 req.ContentLength = 2;
742                                 rs = req.GetRequestStream ();
743                                 rs.WriteByte (0x0d);
744                                 try {
745                                         rs.Close ();
746                                         Assert.Fail ("#B1");
747                                 } catch (WebException ex) {
748                                         // The request was aborted: The request was canceled
749                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
750                                         Assert.IsNotNull (ex.Message, "#B3");
751                                         Assert.IsNull (ex.Response, "#B4");
752                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#B5");
753
754                                         // Cannot close stream until all bytes are written
755                                         Exception inner = ex.InnerException;
756                                         Assert.IsNotNull (inner, "#B6");
757                                         Assert.AreEqual (typeof (IOException), inner.GetType (), "#B7");
758                                         Assert.IsNull (inner.InnerException, "#B8");
759                                         Assert.IsNotNull (inner.Message, "#B9");
760                                 }
761
762                                 req = (HttpWebRequest) WebRequest.Create (url);
763                                 req.Method = "POST";
764                                 req.ContentLength = 2;
765                                 rs = req.GetRequestStream ();
766                                 rs.WriteByte (0x0d);
767                                 rs.WriteByte (0x0d);
768                                 rs.Close ();
769                         }
770                 }
771
772                 [Test] // bug #510642
773                 [Category ("NotWorking")] // #5842
774                 public void GetRequestStream_Write_Overflow ()
775                 {
776                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
777                         string url = "http://" + ep.ToString () + "/test/";
778
779                         // buffered, non-chunked
780                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
781                                 HttpWebRequest req;
782                                 Stream rs;
783                                 byte [] buffer;
784
785                                 req = (HttpWebRequest) WebRequest.Create (url);
786                                 req.Method = "POST";
787                                 req.Timeout = 1000;
788                                 req.ReadWriteTimeout = 2000;
789                                 req.ContentLength = 2;
790
791                                 rs = req.GetRequestStream ();
792                                 rs.WriteByte (0x2c);
793
794                                 buffer = new byte [] { 0x2a, 0x1d };
795                                 try {
796                                         rs.Write (buffer, 0, buffer.Length);
797                                         Assert.Fail ("#A1");
798                                 } catch (ProtocolViolationException ex) {
799                                         // Bytes to be written to the stream exceed
800                                         // Content-Length bytes size specified
801                                         Assert.IsNull (ex.InnerException, "#A2");
802                                         Assert.IsNotNull (ex.Message, "#A3");
803                                 } finally {
804                                         req.Abort ();
805                                 }
806
807                                 req = (HttpWebRequest) WebRequest.Create (url);
808                                 req.Method = "POST";
809                                 req.Timeout = 1000;
810                                 req.ReadWriteTimeout = 2000;
811                                 req.ContentLength = 2;
812
813                                 rs = req.GetRequestStream ();
814
815                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
816                                 try {
817                                         rs.Write (buffer, 0, buffer.Length);
818                                         Assert.Fail ("#B1");
819                                 } catch (ProtocolViolationException ex) {
820                                         // Bytes to be written to the stream exceed
821                                         // Content-Length bytes size specified
822                                         Assert.IsNull (ex.InnerException, "#B2");
823                                         Assert.IsNotNull (ex.Message, "#B3");
824                                 } finally {
825                                         req.Abort ();
826                                 }
827                         }
828
829                         // buffered, chunked
830                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
831                                 HttpWebRequest req;
832                                 Stream rs;
833                                 byte [] buffer;
834
835                                 /*
836                                 req = (HttpWebRequest) WebRequest.Create (url);
837                                 req.Method = "POST";
838                                 req.SendChunked = true;
839                                 req.Timeout = 1000;
840                                 req.ReadWriteTimeout = 2000;
841                                 req.ContentLength = 2;
842
843                                 rs = req.GetRequestStream ();
844                                 rs.WriteByte (0x2c);
845
846                                 buffer = new byte [] { 0x2a, 0x1d };
847                                 rs.Write (buffer, 0, buffer.Length);
848                                 req.Abort ();
849                                 */
850
851                                 req = (HttpWebRequest) WebRequest.Create (url);
852                                 req.Method = "POST";
853                                 req.SendChunked = true;
854                                 req.Timeout = 1000;
855                                 req.ReadWriteTimeout = 2000;
856                                 req.ContentLength = 2;
857
858                                 rs = req.GetRequestStream ();
859
860                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
861                                 rs.Write (buffer, 0, buffer.Length);
862                                 req.Abort ();
863                         }
864
865                         // non-buffered, non-chunked
866                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
867                                 HttpWebRequest req;
868                                 Stream rs;
869                                 byte [] buffer;
870
871                                 req = (HttpWebRequest) WebRequest.Create (url);
872                                 req.AllowWriteStreamBuffering = false;
873                                 req.Method = "POST";
874                                 req.Timeout = 1000;
875                                 req.ReadWriteTimeout = 2000;
876                                 req.ContentLength = 2;
877
878                                 rs = req.GetRequestStream ();
879                                 rs.WriteByte (0x2c);
880
881                                 buffer = new byte [] { 0x2a, 0x1d };
882                                 try {
883                                         rs.Write (buffer, 0, buffer.Length);
884                                         Assert.Fail ("#C1");
885                                 } catch (ProtocolViolationException ex) {
886                                         // Bytes to be written to the stream exceed
887                                         // Content-Length bytes size specified
888                                         Assert.IsNull (ex.InnerException, "#C2");
889                                         Assert.IsNotNull (ex.Message, "#3");
890                                 } finally {
891                                         req.Abort ();
892                                 }
893
894                                 req = (HttpWebRequest) WebRequest.Create (url);
895                                 req.AllowWriteStreamBuffering = false;
896                                 req.Method = "POST";
897                                 req.Timeout = 1000;
898                                 req.ReadWriteTimeout = 2000;
899                                 req.ContentLength = 2;
900
901                                 rs = req.GetRequestStream ();
902
903                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
904                                 try {
905                                         rs.Write (buffer, 0, buffer.Length);
906                                         Assert.Fail ("#D1");
907                                 } catch (ProtocolViolationException ex) {
908                                         // Bytes to be written to the stream exceed
909                                         // Content-Length bytes size specified
910                                         Assert.IsNull (ex.InnerException, "#D2");
911                                         Assert.IsNotNull (ex.Message, "#D3");
912                                 } finally {
913                                         req.Abort ();
914                                 }
915                         }
916
917                         // non-buffered, chunked
918                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
919                                 HttpWebRequest req;
920                                 Stream rs;
921                                 byte [] buffer;
922
923                                 req = (HttpWebRequest) WebRequest.Create (url);
924                                 req.AllowWriteStreamBuffering = false;
925                                 req.Method = "POST";
926                                 req.SendChunked = true;
927                                 req.Timeout = 1000;
928                                 req.ReadWriteTimeout = 2000;
929                                 req.ContentLength = 2;
930
931                                 rs = req.GetRequestStream ();
932                                 rs.WriteByte (0x2c);
933
934                                 buffer = new byte [] { 0x2a, 0x1d };
935                                 rs.Write (buffer, 0, buffer.Length);
936                                 req.Abort ();
937
938                                 req = (HttpWebRequest) WebRequest.Create (url);
939                                 req.AllowWriteStreamBuffering = false;
940                                 req.Method = "POST";
941                                 req.SendChunked = true;
942                                 req.Timeout = 1000;
943                                 req.ReadWriteTimeout = 2000;
944                                 req.ContentLength = 2;
945
946                                 rs = req.GetRequestStream ();
947
948                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
949                                 rs.Write (buffer, 0, buffer.Length);
950                                 req.Abort ();
951                         }
952                 }
953
954                 [Test]
955                 [Ignore ("This test asserts that our code violates RFC 2616")]
956                 public void GetRequestStream_Body_NotAllowed ()
957                 {
958                         string [] methods = new string [] { "GET", "HEAD", "CONNECT",
959                                 "get", "HeAd", "ConNect" };
960
961                         foreach (string method in methods) {
962                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
963                                         "http://localhost:8000");
964                                 req.Method = method;
965                                 try {
966                                         req.GetRequestStream ();
967                                         Assert.Fail ("#1:" + method);
968                                 } catch (ProtocolViolationException ex) {
969                                         Assert.AreEqual (typeof (ProtocolViolationException), ex.GetType (), "#2:" + method);
970                                         Assert.IsNull (ex.InnerException, "#3:" + method);
971                                         Assert.IsNotNull (ex.Message, "#4:" + method);
972                                 }
973                         }
974                 }
975
976                 [Test] // bug #511851
977 #if FEATURE_NO_BSD_SOCKETS
978                 [ExpectedException (typeof (PlatformNotSupportedException))]
979 #endif
980                 public void GetResponse_Request_Aborted ()
981                 {
982                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
983                         string url = "http://" + ep.ToString () + "/test/";
984
985                         using (SocketResponder responder = new SocketResponder (ep, s => EchoRequestHandler (s))) {
986                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
987                                 req.Method = "POST";
988                                 req.Abort ();
989
990                                 try {
991                                         req.GetResponse ();
992                                         Assert.Fail ("#1");
993                                 } catch (WebException ex) {
994                                         // The request was aborted: The request was canceled
995                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
996                                         Assert.IsNull (ex.InnerException, "#3");
997                                         Assert.IsNotNull (ex.Message, "#4");
998                                         Assert.IsNull (ex.Response, "#5");
999                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
1000                                 }
1001                         }
1002                 }
1003
1004                 [Test]
1005                 [Ignore ("This does not timeout any more. That's how MS works when reading small responses")]
1006                 public void ReadTimeout ()
1007                 {
1008                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1009                         string url = "http://" + localEP.ToString () + "/original/";
1010
1011                         using (SocketResponder responder = new SocketResponder (localEP, s => RedirectRequestHandler (s))) {
1012                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1013                                 req.Method = "POST";
1014                                 req.AllowAutoRedirect = false;
1015                                 req.Timeout = 200;
1016                                 req.ReadWriteTimeout = 2000;
1017                                 req.KeepAlive = false;
1018                                 Stream rs = req.GetRequestStream ();
1019                                 rs.Close ();
1020                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1021                                         try {
1022                                                 Stream s = resp.GetResponseStream ();
1023                                                 s.ReadByte ();
1024                                                 Assert.Fail ("#1");
1025                                         } catch (WebException ex) {
1026                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
1027                                                 Assert.IsNull (ex.InnerException, "#3");
1028                                                 Assert.IsNull (ex.Response, "#4");
1029                                                 Assert.AreEqual (WebExceptionStatus.Timeout, ex.Status, "#5");
1030                                         }
1031                                 }
1032                         }
1033                 }
1034
1035                 [Test] // bug #324300
1036 #if FEATURE_NO_BSD_SOCKETS
1037                 [ExpectedException (typeof (PlatformNotSupportedException))]
1038 #endif
1039                 public void AllowAutoRedirect ()
1040                 {
1041                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1042                         string url = "http://" + localEP.ToString () + "/original/";
1043
1044                         // allow autoredirect
1045                         using (SocketResponder responder = new SocketResponder (localEP, s => RedirectRequestHandler (s))) {
1046                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1047                                 req.Method = "POST";
1048                                 req.Timeout = 2000;
1049                                 req.ReadWriteTimeout = 2000;
1050                                 req.KeepAlive = false;
1051                                 Stream rs = req.GetRequestStream ();
1052                                 rs.Close ();
1053                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1054                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
1055                                                 Encoding.UTF8);
1056                                         string body = sr.ReadToEnd ();
1057
1058                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
1059                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1060                                                 localEP.ToString () + "/moved/", "#A2");
1061                                         Assert.AreEqual ("GET", resp.Method, "#A3");
1062                                         Assert.AreEqual ("LOOKS OK", body, "#A4");
1063                                 }
1064                         }
1065
1066                         // do not allow autoredirect
1067                         using (SocketResponder responder = new SocketResponder (localEP, s => RedirectRequestHandler (s))) {
1068                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1069                                 req.Method = "POST";
1070                                 req.AllowAutoRedirect = false;
1071                                 req.Timeout = 1000;
1072                                 req.ReadWriteTimeout = 1000;
1073                                 req.KeepAlive = false;
1074                                 Stream rs = req.GetRequestStream ();
1075                                 rs.Close ();
1076                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1077                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.Found, "#B1");
1078                                         Assert.AreEqual (url, resp.ResponseUri.ToString (), "#B2");
1079                                         Assert.AreEqual ("POST", resp.Method, "#B3");
1080                                 }
1081                         }
1082                 }
1083
1084                 [Test]
1085 #if FEATURE_NO_BSD_SOCKETS
1086                 [ExpectedException (typeof (PlatformNotSupportedException))]
1087 #endif
1088                 public void PostAndRedirect_NoCL ()
1089                 {
1090                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1091                         string url = "http://" + localEP.ToString () + "/original/";
1092
1093                         using (SocketResponder responder = new SocketResponder (localEP, s => RedirectRequestHandler (s))) {
1094                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1095                                 req.Method = "POST";
1096                                 req.Timeout = 2000;
1097                                 req.ReadWriteTimeout = 2000;
1098                                 Stream rs = req.GetRequestStream ();
1099                                 rs.WriteByte (10);
1100                                 rs.Close ();
1101                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1102                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
1103                                                 Encoding.UTF8);
1104                                         string body = sr.ReadToEnd ();
1105
1106                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
1107                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1108                                                 localEP.ToString () + "/moved/", "#A2");
1109                                         Assert.AreEqual ("GET", resp.Method, "#A3");
1110                                         Assert.AreEqual ("LOOKS OK", body, "#A4");
1111                                 }
1112                         }
1113                 }
1114
1115                 [Test]
1116 #if FEATURE_NO_BSD_SOCKETS
1117                 [ExpectedException (typeof (PlatformNotSupportedException))]
1118 #endif
1119                 public void PostAndRedirect_CL ()
1120                 {
1121                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1122                         string url = "http://" + localEP.ToString () + "/original/";
1123
1124                         using (SocketResponder responder = new SocketResponder (localEP, s => RedirectRequestHandler (s))) {
1125                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1126                                 req.Method = "POST";
1127                                 req.Timeout = 2000;
1128                                 req.ReadWriteTimeout = 2000;
1129                                 req.ContentLength  = 1;
1130                                 Stream rs = req.GetRequestStream ();
1131                                 rs.WriteByte (10);
1132                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1133                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
1134                                                 Encoding.UTF8);
1135                                         string body = sr.ReadToEnd ();
1136
1137                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
1138                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1139                                                 localEP.ToString () + "/moved/", "#A2");
1140                                         Assert.AreEqual ("GET", resp.Method, "#A3");
1141                                         Assert.AreEqual ("LOOKS OK", body, "#A4");
1142                                 }
1143                         }
1144                 }
1145
1146                 [Test]
1147 #if FEATURE_NO_BSD_SOCKETS
1148                 [ExpectedException (typeof (PlatformNotSupportedException))]
1149 #endif
1150                 public void PostAnd401 ()
1151                 {
1152                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1153                         string url = "http://" + localEP.ToString () + "/original/";
1154
1155                         using (SocketResponder responder = new SocketResponder (localEP, s => RedirectRequestHandler (s))) {
1156                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1157                                 req.Method = "POST";
1158                                 req.Timeout = 2000;
1159                                 req.ReadWriteTimeout = 2000;
1160                                 req.ContentLength  = 1;
1161                                 Stream rs = req.GetRequestStream ();
1162                                 rs.WriteByte (10);
1163                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1164                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
1165                                                 Encoding.UTF8);
1166                                         string body = sr.ReadToEnd ();
1167
1168                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
1169                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1170                                                 localEP.ToString () + "/moved/", "#A2");
1171                                         Assert.AreEqual ("GET", resp.Method, "#A3");
1172                                         Assert.AreEqual ("LOOKS OK", body, "#A4");
1173                                 }
1174                         }
1175                 }
1176
1177                 [Test] // bug #324347
1178                 [Category ("NotWorking")]
1179                 public void InternalServerError ()
1180                 {
1181                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1182                         string url = "http://" + localEP.ToString () + "/original/";
1183
1184                         // POST
1185                         using (SocketResponder responder = new SocketResponder (localEP, s => InternalErrorHandler (s))) {
1186                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1187                                 req.Method = "POST";
1188                                 req.Timeout = 2000;
1189                                 req.ReadWriteTimeout = 2000;
1190                                 req.KeepAlive = false;
1191                                 Stream rs = req.GetRequestStream ();
1192                                 rs.Close ();
1193
1194                                 try {
1195                                         req.GetResponse ();
1196                                         Assert.Fail ("#A1");
1197                                 } catch (WebException ex) {
1198                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
1199                                         Assert.IsNull (ex.InnerException, "#A3");
1200                                         Assert.IsNotNull (ex.Message, "#A4");
1201                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A5");
1202
1203                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1204                                         Assert.IsNotNull (webResponse, "#A6");
1205                                         Assert.AreEqual ("POST", webResponse.Method, "#A7");
1206                                         webResponse.Close ();
1207                                 }
1208                         }
1209
1210                         // GET
1211                         using (SocketResponder responder = new SocketResponder (localEP, s => InternalErrorHandler (s))) {
1212                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1213                                 req.Method = "GET";
1214                                 req.Timeout = 2000;
1215                                 req.ReadWriteTimeout = 2000;
1216                                 req.KeepAlive = false;
1217
1218                                 try {
1219                                         req.GetResponse ();
1220                                         Assert.Fail ("#B1");
1221                                 } catch (WebException ex) {
1222                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
1223                                         Assert.IsNull (ex.InnerException, "#B3");
1224                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
1225
1226                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1227                                         Assert.IsNotNull (webResponse, "#B5");
1228                                         Assert.AreEqual ("GET", webResponse.Method, "#B6");
1229                                         webResponse.Close ();
1230                                 }
1231                         }
1232                 }
1233
1234                 [Test]
1235                 [Category ("NotWorking")] // #B3 fails; we get a SocketException: An existing connection was forcibly closed by the remote host
1236                 public void NoContentLength ()
1237                 {
1238                         IPEndPoint localEP = NetworkHelpers.LocalEphemeralEndPoint ();
1239                         string url = "http://" + localEP.ToString () + "/original/";
1240
1241                         // POST
1242                         using (SocketResponder responder = new SocketResponder (localEP, s => NoContentLengthHandler (s))) {
1243                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1244                                 req.Method = "POST";
1245                                 req.Timeout = 2000;
1246                                 req.ReadWriteTimeout = 2000;
1247                                 req.KeepAlive = false;
1248                                 Stream rs = req.GetRequestStream ();
1249                                 rs.Close ();
1250
1251                                 try {
1252                                         req.GetResponse ();
1253                                         Assert.Fail ("#A1");
1254                                 } catch (WebException ex) {
1255                                         // The underlying connection was closed:
1256                                         // An unexpected error occurred on a
1257                                         // receive
1258                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
1259                                         Assert.IsNotNull (ex.InnerException, "#A3");
1260                                         Assert.AreEqual (WebExceptionStatus.ReceiveFailure, ex.Status, "#A4");
1261                                         Assert.AreEqual (typeof (IOException), ex.InnerException.GetType (), "#A5");
1262                                         
1263                                         // Unable to read data from the transport connection:
1264                                         // A connection attempt failed because the connected party
1265                                         // did not properly respond after a period of time, or
1266                                         // established connection failed because connected host has
1267                                         // failed to respond
1268                                         IOException ioe = (IOException) ex.InnerException;
1269                                         Assert.IsNotNull (ioe.InnerException, "#A6");
1270                                         Assert.IsNotNull (ioe.Message, "#A7");
1271                                         Assert.AreEqual (typeof (SocketException), ioe.InnerException.GetType (), "#A8");
1272
1273                                         // An existing connection was forcibly
1274                                         // closed by the remote host
1275                                         SocketException soe = (SocketException) ioe.InnerException;
1276                                         Assert.IsNull (soe.InnerException, "#A9");
1277                                         Assert.IsNotNull (soe.Message, "#A10");
1278
1279                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1280                                         Assert.IsNull (webResponse, "#A11");
1281                                 }
1282                         }
1283
1284                         // GET
1285                         using (SocketResponder responder = new SocketResponder (localEP, s => NoContentLengthHandler (s))) {
1286                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1287                                 req.Method = "GET";
1288                                 req.Timeout = 2000;
1289                                 req.ReadWriteTimeout = 2000;
1290                                 req.KeepAlive = false;
1291
1292                                 try {
1293                                         req.GetResponse ();
1294                                         Assert.Fail ("#B1");
1295                                 } catch (WebException ex) {
1296                                         // The remote server returned an error:
1297                                         // (500) Internal Server Error
1298                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
1299                                         Assert.IsNull (ex.InnerException, "#B3");
1300                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
1301
1302                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1303                                         Assert.IsNotNull (webResponse, "#B5");
1304                                         Assert.AreEqual ("GET", webResponse.Method, "#B6");
1305                                         webResponse.Close ();
1306                                 }
1307                         }
1308                 }
1309
1310                 [Test] // bug #513087
1311 #if FEATURE_NO_BSD_SOCKETS
1312                 [ExpectedException (typeof (PlatformNotSupportedException))]
1313 #endif
1314                 public void NonStandardVerb ()
1315                 {
1316                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
1317                         string url = "http://" + ep.ToString () + "/moved/";
1318
1319                         using (SocketResponder responder = new SocketResponder (ep, s => VerbEchoHandler (s))) {
1320                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1321                                 req.Method = "WhatEver";
1322                                 req.KeepAlive = false;
1323                                 req.Timeout = 20000;
1324                                 req.ReadWriteTimeout = 20000;
1325
1326                                 Stream rs = req.GetRequestStream ();
1327                                 rs.Close ();
1328
1329                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1330                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
1331                                                 Encoding.UTF8);
1332                                         string body = sr.ReadToEnd ();
1333
1334                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#1");
1335                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1336                                                 ep.ToString () + "/moved/", "#2");
1337                                         Assert.AreEqual ("WhatEver", resp.Method, "#3");
1338                                         Assert.AreEqual ("WhatEver", body, "#4");
1339                                 }
1340                         }
1341                 }
1342
1343                 [Test]
1344                 [Category ("NotWorking")] // Assert #2 fails
1345                 public void NotModifiedSince ()
1346                 {
1347                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
1348                         string url = "http://" + ep.ToString () + "/test/";
1349
1350                         using (SocketResponder responder = new SocketResponder (ep, s => NotModifiedSinceHandler (s))) {
1351                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1352                                 req.Method = "GET";
1353                                 req.KeepAlive = false;
1354                                 req.Timeout = 20000;
1355                                 req.ReadWriteTimeout = 20000;
1356                                 req.Headers.Add (HttpRequestHeader.IfNoneMatch, "898bbr2347056cc2e096afc66e104653");
1357                                 req.IfModifiedSince = new DateTime (2010, 01, 04);
1358
1359                                 DateTime start = DateTime.Now;
1360                                 HttpWebResponse response = null;
1361
1362                                 try {
1363                                         req.GetResponse ();
1364                                         Assert.Fail ("#1");
1365                                 } catch (WebException e) {
1366                                         response = (HttpWebResponse) e.Response;
1367                                 }
1368
1369                                 Assert.IsNotNull (response, "#2");
1370                                 using (Stream stream = response.GetResponseStream ()) {
1371                                         byte [] buffer = new byte [4096];
1372                                         int bytesRead = stream.Read (buffer, 0, buffer.Length);
1373                                         Assert.AreEqual (0, bytesRead, "#3");
1374                                 }
1375
1376                                 TimeSpan elapsed = DateTime.Now - start;
1377                                 Assert.IsTrue (elapsed.TotalMilliseconds < 2000, "#4");
1378                         }
1379                 }
1380
1381                 [Test] // bug #353495
1382                 [Category ("NotWorking")]
1383                 public void LastModifiedKind ()
1384                 {
1385                         const string reqURL = "http://coffeefaq.com/site/node/25";
1386                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create (reqURL);
1387                         HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
1388                         DateTime lastMod = resp.LastModified;
1389                         //string rawLastMod = resp.Headers ["Last-Modified"];
1390                         resp.Close ();
1391                         //Assert.AreEqual ("Tue, 15 Jan 2008 08:59:59 GMT", rawLastMod, "#1");
1392                         Assert.AreEqual (DateTimeKind.Local, lastMod.Kind, "#2");
1393                         req = (HttpWebRequest) WebRequest.Create (reqURL);
1394                         req.IfModifiedSince = lastMod;
1395                         try {
1396                                 resp = (HttpWebResponse) req.GetResponse ();
1397                                 resp.Close ();
1398                                 Assert.Fail ("Should result in 304");
1399                         } catch (WebException ex) {
1400                                 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#3");
1401                                 Assert.AreEqual (((HttpWebResponse) ex.Response).StatusCode, HttpStatusCode.NotModified, "#4");
1402                         }
1403                 }
1404
1405
1406                 #region Timeout_Bug // https://bugzilla.novell.com/show_bug.cgi?id=317553
1407
1408                 class TimeoutTestHelper {
1409
1410                         string url_to_test;
1411                         internal DateTime? Start { get; private set; }
1412                         internal DateTime? End { get; private set; }
1413                         internal Exception Exception { get; private set; }
1414                         internal string Body { get; private set; }
1415                         internal int TimeOutInMilliSeconds { get; private set; }
1416
1417                         internal TimeoutTestHelper (string url, int timeoutInMilliseconds)
1418                         {
1419                                 url_to_test = url;
1420                                 TimeOutInMilliSeconds = timeoutInMilliseconds;
1421                         }
1422
1423                         internal void LaunchWebRequest ()
1424                         {
1425                                 try {
1426                                         var req = (HttpWebRequest) WebRequest.Create (url_to_test);
1427                                         req.Timeout = TimeOutInMilliSeconds;
1428
1429                                         Start = DateTime.Now;
1430                                         using (var resp = (HttpWebResponse) req.GetResponse ())
1431                                         {
1432                                                 var sr = new StreamReader (resp.GetResponseStream (), Encoding.UTF8);
1433                                                 Body = sr.ReadToEnd ();
1434                                         }
1435                                 } catch (Exception e) {
1436                                         End = DateTime.Now;
1437                                         Exception = e;
1438                                 }
1439                         }
1440                 }
1441
1442                 void TestTimeOut (string url, WebExceptionStatus expectedExceptionStatus)
1443                 {
1444                         var timeoutWorker = new TimeoutTestHelper (url, three_seconds_in_milliseconds);
1445                         var threadStart = new ThreadStart (timeoutWorker.LaunchWebRequest);
1446                         var thread = new Thread (threadStart);
1447                         thread.Start ();
1448                         Thread.Sleep (three_seconds_in_milliseconds * 3);
1449
1450                         if (timeoutWorker.End == null) {
1451 #if MONO_FEATURE_THREAD_ABORT
1452                                 thread.Abort ();
1453 #else
1454                                 thread.Interrupt ();
1455 #endif
1456                                 Assert.Fail ("Thread finished after triple the timeout specified has passed");
1457                         }
1458
1459                         if (!String.IsNullOrEmpty (timeoutWorker.Body)) {
1460                                 if (timeoutWorker.Body == response_of_timeout_handler) {
1461                                         Assert.Fail ("Should not be reached, timeout exception was not thrown and webrequest managed to retrieve proper body");
1462                                 }
1463                                 Assert.Fail ("Should not be reached, timeout exception was not thrown and webrequest managed to retrieve an incorrect body: " + timeoutWorker.Body);
1464                         }
1465
1466                         Assert.IsNotNull (timeoutWorker.Exception, "Exception was not thrown");
1467
1468                         var webEx = timeoutWorker.Exception as WebException;
1469                         Assert.IsNotNull (webEx, "Exception thrown should be WebException, but was: " +
1470                                           timeoutWorker.Exception.GetType ().FullName);
1471
1472                         Assert.AreEqual (expectedExceptionStatus, webEx.Status,
1473                                          "WebException was thrown, but with a wrong status (should be " + expectedExceptionStatus + "): " + webEx.Status);
1474
1475                         Assert.IsFalse (timeoutWorker.End > (timeoutWorker.Start + TimeSpan.FromMilliseconds (three_seconds_in_milliseconds + 500)),
1476                                         "Timeout exception should have been thrown shortly after timeout is reached, however it was at least half-second late");
1477                 }
1478
1479                 [Test] // 1st possible case of https://bugzilla.novell.com/show_bug.cgi?id=MONO74177
1480 #if FEATURE_NO_BSD_SOCKETS
1481                 [ExpectedException (typeof (PlatformNotSupportedException))]
1482 #endif
1483                 public void TestTimeoutPropertyWithServerThatExistsAndRespondsButTooLate ()
1484                 {
1485                         var ep = NetworkHelpers.LocalEphemeralEndPoint ();
1486                         string url = "http://" + ep + "/foobar/";
1487
1488                         using (var responder = new SocketResponder (ep, TimeOutHandler))
1489                         {
1490                                 TestTimeOut (url, WebExceptionStatus.Timeout);
1491                         }
1492                 }
1493
1494                 [Test] // 2nd possible case of https://bugzilla.novell.com/show_bug.cgi?id=MONO74177
1495                 [Category ("RequiresBSDSockets")] // Requires some test refactoring to assert that a PlatformNotSupportedException is thrown, so don't bother (there's plenty of other tests asserting the PlatformNotSupported exceptions).
1496                 public void TestTimeoutWithEndpointThatDoesntExistThrowsConnectFailureBeforeTimeout ()
1497                 {
1498                         string url = "http://127.0.0.1:8271/"; // some endpoint that is unlikely to exist
1499
1500                         // connecting to a non-existing endpoint should throw a ConnectFailure before the timeout is reached
1501                         TestTimeOut (url, WebExceptionStatus.ConnectFailure);
1502                 }
1503
1504                 const string response_of_timeout_handler = "RESPONSE_OF_TIMEOUT_HANDLER";
1505                 const int three_seconds_in_milliseconds = 3000;
1506
1507                 private static byte[] TimeOutHandler (Socket socket)
1508                 {
1509                         socket.Receive (new byte[4096]);
1510
1511                         Thread.Sleep (three_seconds_in_milliseconds * 2);
1512
1513                         var sw = new StringWriter ();
1514                         sw.WriteLine ("HTTP/1.1 200 OK");
1515                         sw.WriteLine ("Content-Type: text/plain");
1516                         sw.WriteLine ("Content-Length: " + response_of_timeout_handler.Length);
1517                         sw.WriteLine ();
1518                         sw.Write (response_of_timeout_handler);
1519                         sw.Flush ();
1520
1521                         return Encoding.UTF8.GetBytes (sw.ToString ());
1522                 }
1523
1524                 #endregion
1525
1526                 internal static byte [] EchoRequestHandler (Socket socket)
1527                 {
1528                         MemoryStream ms = new MemoryStream ();
1529                         byte [] buffer = new byte [4096];
1530                         int bytesReceived = socket.Receive (buffer);
1531                         while (bytesReceived > 0) {
1532                                 ms.Write (buffer, 0, bytesReceived);
1533                                  // We don't check for Content-Length or anything else here, so we give the client a little time to write
1534                                  // after sending the headers
1535                                 Thread.Sleep (200);
1536                                 if (socket.Available > 0) {
1537                                         bytesReceived = socket.Receive (buffer);
1538                                 } else {
1539                                         bytesReceived = 0;
1540                                 }
1541                         }
1542                         ms.Flush ();
1543                         ms.Position = 0;
1544                         StreamReader sr = new StreamReader (ms, Encoding.UTF8);
1545                         string request = sr.ReadToEnd ();
1546
1547                         StringWriter sw = new StringWriter ();
1548                         sw.WriteLine ("HTTP/1.1 200 OK");
1549                         sw.WriteLine ("Content-Type: text/xml");
1550                         sw.WriteLine ("Content-Length: " + request.Length.ToString (CultureInfo.InvariantCulture));
1551                         sw.WriteLine ();
1552                         sw.Write (request);
1553                         sw.Flush ();
1554
1555                         return Encoding.UTF8.GetBytes (sw.ToString ());
1556                 }
1557
1558                 static byte [] RedirectRequestHandler (Socket socket)
1559                 {
1560                         MemoryStream ms = new MemoryStream ();
1561                         byte [] buffer = new byte [4096];
1562                         int bytesReceived = socket.Receive (buffer);
1563                         while (bytesReceived > 0) {
1564                                 ms.Write (buffer, 0, bytesReceived);
1565                                  // We don't check for Content-Length or anything else here, so we give the client a little time to write
1566                                  // after sending the headers
1567                                 Thread.Sleep (200);
1568                                 if (socket.Available > 0) {
1569                                         bytesReceived = socket.Receive (buffer);
1570                                 } else {
1571                                         bytesReceived = 0;
1572                                 }
1573                         }
1574                         ms.Flush ();
1575                         ms.Position = 0;
1576                         string statusLine = null;
1577                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1578                                 statusLine = sr.ReadLine ();
1579                         }
1580
1581                         StringWriter sw = new StringWriter ();
1582                         if (statusLine.StartsWith ("POST /original/")) {
1583                                 sw.WriteLine ("HTTP/1.0 302 Found");
1584                                 EndPoint ep = socket.LocalEndPoint;
1585                                 sw.WriteLine ("Location: " + "http://" + ep.ToString () + "/moved/");
1586                                 sw.WriteLine ();
1587                                 sw.Flush ();
1588                         } else if (statusLine.StartsWith ("GET /moved/")) {
1589                                 sw.WriteLine ("HTTP/1.0 200 OK");
1590                                 sw.WriteLine ("Content-Type: text/plain");
1591                                 sw.WriteLine ("Content-Length: 8");
1592                                 sw.WriteLine ();
1593                                 sw.Write ("LOOKS OK");
1594                                 sw.Flush ();
1595                         } else {
1596                                 sw.WriteLine ("HTTP/1.0 500 Too Lazy");
1597                                 sw.WriteLine ();
1598                                 sw.Flush ();
1599                         }
1600
1601                         return Encoding.UTF8.GetBytes (sw.ToString ());
1602                 }
1603
1604                 static byte [] InternalErrorHandler (Socket socket)
1605                 {
1606                         byte [] buffer = new byte [4096];
1607                         int bytesReceived = socket.Receive (buffer);
1608                         while (bytesReceived > 0) {
1609                                  // We don't check for Content-Length or anything else here, so we give the client a little time to write
1610                                  // after sending the headers
1611                                 Thread.Sleep (200);
1612                                 if (socket.Available > 0) {
1613                                         bytesReceived = socket.Receive (buffer);
1614                                 } else {
1615                                         bytesReceived = 0;
1616                                 }
1617                         }
1618                         StringWriter sw = new StringWriter ();
1619                         sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1620                         sw.WriteLine ("Content-Length: 0");
1621                         sw.WriteLine ();
1622                         sw.Flush ();
1623
1624                         return Encoding.UTF8.GetBytes (sw.ToString ());
1625                 }
1626
1627                 static byte [] NoContentLengthHandler (Socket socket)
1628                 {
1629                         StringWriter sw = new StringWriter ();
1630                         sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1631                         sw.WriteLine ();
1632                         sw.Flush ();
1633
1634                         return Encoding.UTF8.GetBytes (sw.ToString ());
1635                 }
1636
1637                 static byte [] NotModifiedSinceHandler (Socket socket)
1638                 {
1639                         StringWriter sw = new StringWriter ();
1640                         sw.WriteLine ("HTTP/1.1 304 Not Modified");
1641                         sw.WriteLine ("Date: Fri, 06 Feb 2009 12:50:26 GMT");
1642                         sw.WriteLine ("Server: Apache/2.2.6 (Debian) PHP/5.2.6-2+b1 with Suhosin-Patch mod_ssl/2.2.6 OpenSSL/0.9.8g");
1643                         sw.WriteLine ("Not-Modified-Since: Sun, 08 Feb 2009 08:49:26 GMT");
1644                         sw.WriteLine ("ETag: 898bbr2347056cc2e096afc66e104653");
1645                         sw.WriteLine ("Connection: close");
1646                         sw.WriteLine ();
1647                         sw.Flush ();
1648
1649                         return Encoding.UTF8.GetBytes (sw.ToString ());
1650                 }
1651
1652                 static byte [] VerbEchoHandler (Socket socket)
1653                 {
1654                         MemoryStream ms = new MemoryStream ();
1655                         byte [] buffer = new byte [4096];
1656                         int bytesReceived = socket.Receive (buffer);
1657                         while (bytesReceived > 0) {
1658                                 ms.Write (buffer, 0, bytesReceived);
1659                                  // We don't check for Content-Length or anything else here, so we give the client a little time to write
1660                                  // after sending the headers
1661                                 Thread.Sleep (200);
1662                                 if (socket.Available > 0) {
1663                                         bytesReceived = socket.Receive (buffer);
1664                                 } else {
1665                                         bytesReceived = 0;
1666                                 }
1667                         }
1668                         ms.Flush ();
1669                         ms.Position = 0;
1670                         string statusLine = null;
1671                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1672                                 statusLine = sr.ReadLine ();
1673                         }
1674
1675                         string verb = "DEFAULT";
1676                         if (statusLine != null) {
1677                                 string [] parts = statusLine.Split (' ');
1678                                 if (parts.Length > 0)
1679                                         verb = parts [0];
1680                         }
1681
1682                         StringWriter sw = new StringWriter ();
1683                         sw.WriteLine ("HTTP/1.1 200 OK");
1684                         sw.WriteLine ("Content-Type: text/plain");
1685                         sw.WriteLine ("Content-Length: " + verb.Length);
1686                         sw.WriteLine ();
1687                         sw.Write (verb);
1688                         sw.Flush ();
1689
1690                         return Encoding.UTF8.GetBytes (sw.ToString ());
1691                 }
1692
1693                 static byte [] PostAnd401Handler (Socket socket)
1694                 {
1695                         MemoryStream ms = new MemoryStream ();
1696                         byte [] buffer = new byte [4096];
1697                         int bytesReceived = socket.Receive (buffer);
1698                         while (bytesReceived > 0) {
1699                                 ms.Write (buffer, 0, bytesReceived);
1700                                  // We don't check for Content-Length or anything else here, so we give the client a little time to write
1701                                  // after sending the headers
1702                                 Thread.Sleep (200);
1703                                 if (socket.Available > 0) {
1704                                         bytesReceived = socket.Receive (buffer);
1705                                 } else {
1706                                         bytesReceived = 0;
1707                                 }
1708                         }
1709                         ms.Flush ();
1710                         ms.Position = 0;
1711                         string statusLine = null;
1712                         bool have_auth = false;
1713                         int cl = -1;
1714                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1715                                 string l;
1716                                 while ((l = sr.ReadLine ()) != null) {
1717                                         if (statusLine == null) {
1718                                                 statusLine = l;
1719                                         } else if (l.StartsWith ("Authorization:")) {
1720                                                 have_auth = true;
1721                                         } else if (l.StartsWith ("Content-Length:")) {
1722                                                 cl = Int32.Parse (l.Substring ("content-length: ".Length));
1723                                         }
1724                                 }
1725                         }
1726
1727                         StringWriter sw = new StringWriter ();
1728                         if (!have_auth) {
1729                                 sw.WriteLine ("HTTP/1.0 401 Invalid Credentials");
1730                                 sw.WriteLine ("WWW-Authenticate: basic Yeah");
1731                                 sw.WriteLine ();
1732                                 sw.Flush ();
1733                         } else if (cl > 0 && statusLine.StartsWith ("POST ")) {
1734                                 sw.WriteLine ("HTTP/1.0 200 OK");
1735                                 sw.WriteLine ("Content-Type: text/plain");
1736                                 sw.WriteLine ("Content-Length: 8");
1737                                 sw.WriteLine ();
1738                                 sw.Write ("LOOKS OK");
1739                                 sw.Flush ();
1740                         } else {
1741                                 sw.WriteLine ("HTTP/1.0 500 test failed");
1742                                 sw.WriteLine ("Content-Length: 0");
1743                                 sw.WriteLine ();
1744                                 sw.Flush ();
1745                         }
1746
1747                         return Encoding.UTF8.GetBytes (sw.ToString ());
1748                 }
1749                 [Test]
1750 #if FEATURE_NO_BSD_SOCKETS
1751                 [ExpectedException (typeof (PlatformNotSupportedException))]
1752 #endif
1753                 public void NtlmAuthentication ()
1754                 {
1755                         NtlmServer server = new NtlmServer ();
1756                         server.Start ();
1757
1758                         string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
1759                         HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
1760                         request.Timeout = 5000;
1761                         request.Credentials = new NetworkCredential ("user", "password", "domain");
1762                         HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
1763                         string res = null;
1764                         using (StreamReader reader = new StreamReader (resp.GetResponseStream ())) {
1765                                 res = reader.ReadToEnd ();
1766                         }
1767                         resp.Close ();
1768                         server.Stop ();
1769                         Assert.AreEqual ("OK", res);
1770                 }
1771
1772                 class NtlmServer : HttpServer {
1773                         public string Where = "";
1774                         protected override void Run ()
1775                         {
1776                                 Where = "before accept";
1777                                 Socket client = sock.Accept ();
1778                                 NetworkStream ns = new NetworkStream (client, false);
1779                                 StreamReader reader = new StreamReader (ns, Encoding.ASCII);
1780                                 string line;
1781                                 Where = "first read";
1782                                 while ((line = reader.ReadLine ()) != null) {
1783                                         if (line.Trim () == String.Empty) {
1784                                                 break;
1785                                         }
1786                                 }
1787                                 Where = "first write";
1788                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1789                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1790                                         "WWW-Authenticate: ignore\r\n" +
1791                                         "WWW-Authenticate: NTLM\r\n" +
1792                                         "WWW-Authenticate: ignore,K\r\n" +
1793                                                 "Content-Length: 5\r\n\r\nWRONG");
1794
1795                                 writer.Flush ();
1796                                 Where = "second read";
1797                                 while ((line = reader.ReadLine ()) != null) {
1798                                         if (line.Trim () == String.Empty) {
1799                                                 break;
1800                                         }
1801                                 }
1802                                 Where = "second write";
1803                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1804                                                 "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggAC8GDhqIONH3sAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=\r\n" +
1805                                                 "Content-Length: 5\r\n\r\nWRONG");
1806                                 writer.Flush ();
1807
1808                                 Where = "third read";
1809                                 while ((line = reader.ReadLine ()) != null) {
1810                                         if (line.Trim () == String.Empty) {
1811                                                 break;
1812                                         }
1813                                 }
1814                                 Where = "third write";
1815                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1816                                                 "Keep-Alive: true\r\n" +
1817                                                 "Content-Length: 2\r\n\r\nOK");
1818                                 writer.Flush ();
1819                                 Thread.Sleep (1000);
1820                                 writer.Close ();
1821                                 reader.Close ();
1822                                 client.Close ();
1823                         }
1824                 }
1825
1826                 class BadChunkedServer : HttpServer {
1827                         protected override void Run ()
1828                         {
1829                                 Socket client = sock.Accept ();
1830                                 NetworkStream ns = new NetworkStream (client, true);
1831                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1832                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1833                                                 "Transfer-Encoding: chunked\r\n" +
1834                                                 "Connection: close\r\n" +
1835                                                 "Content-Type: text/plain; charset=UTF-8\r\n\r\n");
1836
1837                                 // This body lacks a 'last-chunk' (see RFC 2616)
1838                                 writer.Write ("10\r\n1234567890123456\r\n");
1839                                 writer.Flush ();
1840                                 client.Shutdown (SocketShutdown.Send);
1841                                 Thread.Sleep (1000);
1842                                 writer.Close ();
1843                         }
1844                 }
1845
1846                 class AcceptAllPolicy : ICertificatePolicy {
1847                         public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
1848                         {
1849                                 return true;
1850                         }
1851                 }
1852
1853                 abstract class HttpServer
1854                 {
1855                         protected Socket sock;
1856                         protected Exception error;
1857                         protected ManualResetEvent evt;
1858
1859                         public HttpServer ()
1860                         {
1861                                 sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1862                                 sock.Bind (new IPEndPoint (IPAddress.Loopback, 0));
1863                                 sock.Listen (1);
1864                         }
1865
1866                         public void Start ()
1867                         {
1868                                 evt = new ManualResetEvent (false);
1869                                 Thread th = new Thread (new ThreadStart (Run));
1870                                 th.Start ();
1871                         }
1872
1873                         public void Stop ()
1874                         {
1875                                 evt.Set ();
1876                                 sock.Close ();
1877                         }
1878                         
1879                         public IPAddress IPAddress {
1880                                 get { return ((IPEndPoint) sock.LocalEndPoint).Address; }
1881                         }
1882                         
1883                         public int Port {
1884                                 get { return ((IPEndPoint) sock.LocalEndPoint).Port; }
1885                         }
1886
1887                         public Exception Error { 
1888                                 get { return error; }
1889                         }
1890
1891                         protected abstract void Run ();
1892                 }
1893
1894                 [Test]
1895 #if FEATURE_NO_BSD_SOCKETS
1896                 [ExpectedException (typeof (PlatformNotSupportedException))]
1897 #endif
1898                 public void BeginGetRequestStream ()
1899                 {
1900                         this.DoRequest (
1901                         (r, c) =>
1902                         {
1903                                 r.Method = "POST";
1904                                 r.ContentLength = 0;
1905                                 r.BeginGetRequestStream ((a) =>
1906                                 {
1907                                 using (Stream s = r.EndGetRequestStream (a)) { };
1908                                 c.Set();
1909                                 },
1910                                 null);
1911                         },
1912                         (c) => { });
1913                 }
1914
1915                 [Test]
1916 #if FEATURE_NO_BSD_SOCKETS
1917                 [ExpectedException (typeof (PlatformNotSupportedException))]
1918 #endif
1919                 public void BeginGetRequestStreamNoClose ()
1920                 {
1921                         this.DoRequest (
1922                         (r, c) => {
1923                                 r.Method = "POST";
1924                                 r.ContentLength = 1;
1925                                 r.BeginGetRequestStream ((a) =>
1926                                 {
1927                                         r.EndGetRequestStream (a);
1928                                         c.Set ();
1929                                 },
1930                                 null);
1931                         },
1932                         (c) => {});
1933                 }
1934
1935                 [Test]
1936 #if FEATURE_NO_BSD_SOCKETS
1937                 [ExpectedException (typeof (PlatformNotSupportedException))]
1938 #endif
1939                 public void BeginGetRequestStreamCancelIfNotAllBytesWritten ()
1940                 {
1941                         this.DoRequest (
1942                         (r, c) =>
1943                         {
1944                                 r.Method = "POST";
1945                                 r.ContentLength = 10;
1946                                 r.BeginGetRequestStream ((a) =>
1947                                 {
1948                                         WebException ex = ExceptionAssert.Throws<WebException> (() =>
1949                                         {
1950                                                 using (Stream s = r.EndGetRequestStream (a)) {
1951                                                 }
1952                                         }
1953                                 );
1954                                 Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
1955                                 c.Set();
1956                                 },
1957                                 null);
1958                         },
1959                         (c) => { });
1960                 }
1961
1962                 [Test]
1963 #if FEATURE_NO_BSD_SOCKETS
1964                 [ExpectedException (typeof (PlatformNotSupportedException))]
1965 #endif
1966                 public void GetRequestStream2 ()
1967                 {
1968                         this.DoRequest (
1969                         (r, c) =>
1970                         {
1971                                 r.Method = "POST";
1972                                 r.ContentLength = data64KB.Length;
1973                                 using (Stream s = r.GetRequestStream ()) {
1974                                         s.Write (data64KB, 0, data64KB.Length);
1975                                 }
1976                                 c.Set ();
1977                         },
1978                         (c) => { });
1979                 }
1980
1981                 [Test]
1982 #if FEATURE_NO_BSD_SOCKETS
1983                 [ExpectedException (typeof (PlatformNotSupportedException))]
1984 #endif
1985                 public void GetRequestStreamNotAllBytesWritten ()
1986                 {
1987                         this.DoRequest (
1988                         (r, c) =>
1989                         {
1990                                 r.Method = "POST";
1991                                 r.ContentLength = data64KB.Length;
1992                                 WebException ex = ExceptionAssert.Throws<WebException> (() => r.GetRequestStream ().Close ());
1993                                 Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
1994                                 c.Set ();
1995                         },
1996                         (c) => {});
1997                 }
1998
1999                 [Test]
2000 #if FEATURE_NO_BSD_SOCKETS
2001                 [ExpectedException (typeof (PlatformNotSupportedException))]
2002 #endif
2003                 public void GetRequestStreamTimeout ()
2004                 {
2005                         this.DoRequest (
2006                         (r, c) =>
2007                         {
2008                                 r.Method = "POST";
2009                                 r.ContentLength = data64KB.Length;
2010                                 r.Timeout = 100;
2011                                 WebException ex = ExceptionAssert.Throws<WebException> (() => r.GetRequestStream ());
2012                                 Assert.IsTrue (ex.Status == WebExceptionStatus.Timeout || ex.Status == WebExceptionStatus.ConnectFailure);
2013                                 c.Set();
2014                         });
2015                 }
2016
2017                 [Test]
2018 #if FEATURE_NO_BSD_SOCKETS
2019                 [ExpectedException (typeof (PlatformNotSupportedException))]
2020 #endif
2021                 public void BeginWrite ()
2022                 {
2023                         byte[] received = new byte[data64KB.Length];
2024
2025                         this.DoRequest (
2026                         (r, c) =>
2027                         {
2028                                 r.Method = "POST";
2029                                 r.ContentLength = data64KB.Length;
2030
2031                                 Stream s = r.GetRequestStream ();
2032                                 s.BeginWrite (data64KB, 0, data64KB.Length,
2033                                 (a) =>
2034                                 {
2035                                         s.EndWrite (a);
2036                                         s.Close ();
2037                                         r.GetResponse ().Close ();
2038                                         c.Set();
2039                                 },
2040                                 null);
2041                         },
2042                         (c) =>
2043                         {
2044                                 c.Request.InputStream.ReadAll (received, 0, received.Length);
2045                                 c.Response.StatusCode = 204;
2046                                 c.Response.Close ();
2047                         });
2048
2049                         Assert.AreEqual (data64KB, received);
2050                 }
2051
2052                 [Test]
2053 #if FEATURE_NO_BSD_SOCKETS
2054                 [ExpectedException (typeof (PlatformNotSupportedException))]
2055 #endif
2056                 public void BeginWriteAfterAbort ()
2057                 {
2058                         byte [] received = new byte [data64KB.Length];
2059
2060                         this.DoRequest (
2061                         (r, c) =>
2062                         {
2063                                 r.Method = "POST";
2064                                 r.ContentLength = data64KB.Length;
2065
2066                                 Stream s = r.GetRequestStream ();
2067                                 r.Abort();
2068
2069                                 WebException ex = ExceptionAssert.Throws<WebException> (() => s.BeginWrite (data64KB, 0, data64KB.Length, null, null));
2070                                 Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
2071
2072                                 c.Set();
2073                         },
2074                         (c) =>
2075                         {
2076                                 //c.Request.InputStream.ReadAll (received, 0, received.Length);
2077                                 //c.Response.StatusCode = 204;
2078                                 //c.Response.Close();
2079                         });
2080                 }
2081
2082                 [Test]
2083 #if FEATURE_NO_BSD_SOCKETS
2084                 [ExpectedException (typeof (PlatformNotSupportedException))]
2085 #endif
2086                 public void PrematureStreamCloseAborts ()
2087                 {
2088                         byte [] received = new byte [data64KB.Length];
2089
2090                         this.DoRequest (
2091                         (r, c) =>
2092                         {
2093                                 r.Method = "POST";
2094                                 r.ContentLength = data64KB.Length * 2;
2095
2096                                 Stream s = r.GetRequestStream ();
2097                                 s.Write (data64KB, 0, data64KB.Length);
2098
2099                                 WebException ex = ExceptionAssert.Throws<WebException>(() => s.Close());
2100                                 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
2101
2102                                 c.Set();
2103                         },
2104                         (c) =>
2105                         {
2106                                 c.Request.InputStream.ReadAll (received, 0, received.Length);
2107 //                              c.Response.StatusCode = 204;
2108 //                              c.Response.Close ();
2109                         });
2110                 }
2111
2112                 [Test]
2113 #if FEATURE_NO_BSD_SOCKETS
2114                 [ExpectedException (typeof (PlatformNotSupportedException))]
2115 #endif
2116                 public void Write ()
2117                 {
2118                         byte [] received = new byte [data64KB.Length];
2119
2120                         this.DoRequest (
2121                         (r, c) =>
2122                         {
2123                                 r.Method = "POST";
2124                                 r.ContentLength = data64KB.Length;
2125
2126                                 using (Stream s = r.GetRequestStream ()) {
2127                                         s.Write (data64KB, 0, data64KB.Length);
2128                                 }
2129
2130                                 r.GetResponse ().Close ();
2131                                 c.Set ();
2132                         },
2133                         (c) =>
2134                         {
2135                                 c.Request.InputStream.ReadAll (received, 0, received.Length);
2136                                 c.Response.StatusCode = 204;
2137                                 c.Response.Close ();
2138                         });
2139
2140                         Assert.AreEqual(data64KB, received);
2141                 }
2142
2143                 /*
2144                 Invalid test: it does not work on linux.
2145                 [pid 30973] send(9, "POST / HTTP/1.1\r\nContent-Length:"..., 89, 0) = 89
2146                 Abort set
2147                 [pid 30970] send(16, "HTTP/1.1 200 OK\r\nServer: Mono-HT"..., 133, 0) = 133
2148                 Calling abort
2149                 [pid 30970] close(16)                   = 0
2150                 Closing!!!
2151                 [pid 30980] send(9, "\213t\326\350\312u\36n\234\351\225L\r\243a\200\226\371\350F\271~oZ\32\270\24\226z4\211\345"..., 65536, 0) = 65536
2152                 Writing...
2153                 [pid 30966] close(4)                    = 0
2154                 OK
2155                  *
2156                  The server sideis closed (FD 16) and the send on the client side (FD 9) succeeds.
2157                 [Test]
2158                 [Category("NotWorking")]
2159                 public void WriteServerAborts ()
2160                 {
2161                         ManualResetEvent abort = new ManualResetEvent (false);
2162                         byte [] received = new byte [data64KB.Length];
2163
2164                         this.DoRequest (
2165                         (r, c) =>
2166                         {
2167                                 r.Method = "POST";
2168                                 r.ContentLength = data64KB.Length;
2169
2170                                 using (Stream s = r.GetRequestStream()) {
2171                                         abort.Set();
2172                                         Thread.Sleep(100);
2173                                         IOException ex = ExceptionAssert.Throws<IOException> (() => s.Write(data64KB, 0, data64KB.Length));
2174                                 }
2175
2176                                 c.Set();
2177                         },
2178                         (c) =>
2179                         {
2180                                 abort.WaitOne();
2181                                 c.Response.Abort();
2182                         });
2183                 }
2184                 **/
2185
2186                 [Test]
2187 #if FEATURE_NO_BSD_SOCKETS
2188                 [ExpectedException (typeof (PlatformNotSupportedException))]
2189 #endif
2190                 public void Read ()
2191                 {
2192                         byte [] received = new byte [data64KB.Length];
2193
2194                         this.DoRequest (
2195                         (r, c) =>
2196                         {
2197                                 using (HttpWebResponse x = (HttpWebResponse) r.GetResponse ())
2198                                 using (Stream s = x.GetResponseStream()) {
2199                                         s.ReadAll (received, 0, received.Length);
2200                                 }
2201
2202                                 c.Set ();
2203                         },
2204                         (c) =>
2205                         {
2206                                 c.Response.StatusCode = 200;
2207                                 c.Response.ContentLength64 = data64KB.Length;
2208                                 c.Response.OutputStream.Write (data64KB, 0, data64KB.Length);
2209                                 c.Response.OutputStream.Close ();
2210                                 c.Response.Close ();
2211                         });
2212
2213                         Assert.AreEqual (data64KB, received);
2214                 }
2215
2216                 [Test]
2217 #if FEATURE_NO_BSD_SOCKETS
2218                 [ExpectedException (typeof (PlatformNotSupportedException))]
2219 #endif
2220                 public void ReadTimeout2 ()
2221                 {
2222                         byte [] received = new byte [data64KB.Length];
2223
2224                         this.DoRequest (
2225                         (r, c) =>
2226                         {
2227                                 r.ReadWriteTimeout = 10;
2228                                 using (HttpWebResponse x = (HttpWebResponse) r.GetResponse ())
2229                                 using (Stream s = x.GetResponseStream ()) {
2230                                         WebException ex = ExceptionAssert.Throws<WebException> (() => s.ReadAll (received, 0, received.Length));
2231                                         Assert.AreEqual (ex.Status, WebExceptionStatus.Timeout);
2232                                 }
2233
2234                                 c.Set();
2235                         },
2236                         (c) =>
2237                         {
2238                                 c.Response.StatusCode = 200;
2239                                 c.Response.ContentLength64 = data64KB.Length;
2240                                 c.Response.OutputStream.Write (data64KB, 0, data64KB.Length / 2);
2241                                 Thread.Sleep (1000);
2242 //                              c.Response.OutputStream.Write (data64KB, data64KB.Length / 2, data64KB.Length / 2);
2243                                 c.Response.OutputStream.Close ();
2244                                 c.Response.Close ();
2245                         });
2246                 }
2247
2248                 [Test]
2249 #if FEATURE_NO_BSD_SOCKETS
2250                 [ExpectedException (typeof (PlatformNotSupportedException))]
2251 #endif
2252                 public void ReadServerAborted ()
2253                 {
2254                         byte [] received = new byte [data64KB.Length];
2255
2256                         this.DoRequest (
2257                         (r, c) =>
2258                         {
2259                                 using (HttpWebResponse x = (HttpWebResponse) r.GetResponse ())
2260                                 using (Stream s = x.GetResponseStream ()) {
2261                                         Assert.AreEqual (1, s.ReadAll (received, 0, received.Length));
2262                                 }
2263
2264                                 c.Set();
2265                         },
2266                         (c) =>
2267                         {
2268                                 c.Response.StatusCode = 200;
2269                                 c.Response.ContentLength64 = data64KB.Length;
2270                                 c.Response.OutputStream.Write (data64KB, 0, 1);
2271                                 c.Response.Abort ();
2272                         });
2273                 }
2274
2275                 [Test]
2276 #if FEATURE_NO_BSD_SOCKETS
2277                 [ExpectedException (typeof (PlatformNotSupportedException))]
2278 #endif
2279                 public void BeginGetResponse2 ()
2280                 {
2281                         byte [] received = new byte [data64KB.Length];
2282
2283                         this.DoRequest (
2284                         (r, c) =>
2285                         {
2286                                 r.BeginGetResponse ((a) =>
2287                                 {
2288                                         using (HttpWebResponse x = (HttpWebResponse) r.EndGetResponse (a))
2289                                         using (Stream s = x.GetResponseStream ()) {
2290                                                 s.ReadAll (received, 0, received.Length);
2291                                         }
2292
2293                                         c.Set();
2294                                 }, null);
2295                         },
2296                         (c) =>
2297                         {
2298                                 c.Response.StatusCode = 200;
2299                                 c.Response.ContentLength64 = data64KB.Length;
2300                                 c.Response.OutputStream.Write (data64KB, 0, data64KB.Length);
2301                                 c.Response.OutputStream.Close ();
2302                                 c.Response.Close ();
2303                         });
2304
2305                         Assert.AreEqual (data64KB, received);
2306                 }
2307
2308                 [Test]
2309 #if FEATURE_NO_BSD_SOCKETS
2310                 [ExpectedException (typeof (PlatformNotSupportedException))]
2311 #endif
2312                 public void BeginGetResponseAborts ()
2313                 {
2314                         ManualResetEvent aborted = new ManualResetEvent(false);
2315
2316                         this.DoRequest (
2317                         (r, c) =>
2318                         {
2319                                 r.BeginGetResponse((a) =>
2320                                 {
2321                                         WebException ex = ExceptionAssert.Throws<WebException> (() => r.EndGetResponse (a));
2322                                         Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
2323                                         c.Set ();
2324                                 }, null);
2325
2326                                 aborted.WaitOne ();
2327                                 r.Abort ();
2328                         },
2329                         (c) =>
2330                         {
2331                                 aborted.Set ();
2332 //                              Thread.Sleep (100);
2333 //                              c.Response.StatusCode = 200;
2334 //                              c.Response.ContentLength64 = 0;
2335 //                              c.Response.Close ();
2336                         });
2337
2338                         return;
2339                 }
2340                 
2341                 [Test]
2342 #if FEATURE_NO_BSD_SOCKETS
2343                 [ExpectedException (typeof (PlatformNotSupportedException))]
2344 #endif
2345                 public void TestLargeDataReading ()
2346                 {
2347                         int near2GBStartPosition = rand.Next (int.MaxValue - 500, int.MaxValue);
2348                         AutoResetEvent readyGetLastPortionEvent = new AutoResetEvent (false);
2349                         Exception testException = null;
2350
2351                         DoRequest (
2352                         (request, waitHandle) =>
2353                         {
2354                                 try
2355                                 {
2356                                         const int timeoutMs = 5000;
2357
2358                                         request.Timeout = timeoutMs;
2359                                         request.ReadWriteTimeout = timeoutMs;
2360
2361                                         WebResponse webResponse = request.GetResponse ();
2362                                         Stream webResponseStream = webResponse.GetResponseStream ();
2363                                         Assert.IsNotNull (webResponseStream, null, "#1");
2364                                         
2365                                         Type webConnectionStreamType = webResponseStream.GetType ();
2366                                         FieldInfo totalReadField = webConnectionStreamType.GetField ("totalRead", BindingFlags.NonPublic | BindingFlags.Instance);
2367                                         Assert.IsNotNull (totalReadField, "#2");
2368                                         totalReadField.SetValue (webResponseStream, near2GBStartPosition);
2369                                         
2370                                         byte[] readBuffer = new byte[int.MaxValue - near2GBStartPosition];
2371                                         Assert.AreEqual (webResponseStream.Read (readBuffer, 0, readBuffer.Length), readBuffer.Length, "#3");
2372                                         readyGetLastPortionEvent.Set ();
2373                                         Assert.IsTrue (webResponseStream.Read (readBuffer, 0, readBuffer.Length) > 0);
2374                                         readyGetLastPortionEvent.Set ();
2375                                         
2376                                         webResponse.Close();
2377                                 }
2378                                 catch (Exception e)
2379                                 {
2380                                         testException = e;
2381                                 }
2382                                 finally
2383                                 {
2384                                         waitHandle.Set ();
2385                                 }
2386                         },
2387                         processor =>
2388                         {
2389                                 processor.Request.InputStream.Close ();
2390                                 
2391                                 HttpListenerResponse response = processor.Response;
2392                                 response.SendChunked = true;
2393                                 
2394                                 Stream outputStream = response.OutputStream;
2395                                 var writeBuffer = new byte[int.MaxValue - near2GBStartPosition];
2396                                 outputStream.Write (writeBuffer, 0, writeBuffer.Length);
2397                                 readyGetLastPortionEvent.WaitOne ();
2398                                 outputStream.Write (writeBuffer, 0, writeBuffer.Length);
2399                                 readyGetLastPortionEvent.WaitOne ();
2400                                 
2401                                 response.Close();
2402                         });
2403
2404                         if (testException != null)
2405                                 throw testException;
2406                 }
2407
2408                 void DoRequest (Action<HttpWebRequest, EventWaitHandle> request)
2409                 {
2410                         int port = NetworkHelpers.FindFreePort ();
2411
2412                         ManualResetEvent completed = new ManualResetEvent (false);
2413                         Uri address = new Uri (string.Format ("http://localhost:{0}", port));
2414                         HttpWebRequest client = (HttpWebRequest) WebRequest.Create (address);
2415
2416                         request (client, completed);
2417
2418                         if (!completed.WaitOne (10000))
2419                                 Assert.Fail ("Test hung");
2420                 }
2421
2422                 void DoRequest (Action<HttpWebRequest, EventWaitHandle> request, Action<HttpListenerContext> processor)
2423                 {
2424                         int port = NetworkHelpers.FindFreePort ();
2425
2426                         ManualResetEvent [] completed = new ManualResetEvent [2];
2427                         completed [0] = new ManualResetEvent (false);
2428                         completed [1] = new ManualResetEvent (false);
2429
2430                         using (ListenerScope scope = new ListenerScope (processor, port, completed [0])) {
2431                                 Uri address = new Uri (string.Format ("http://localhost:{0}", port));
2432                                 HttpWebRequest client = (HttpWebRequest) WebRequest.Create (address);
2433
2434                                 ThreadPool.QueueUserWorkItem ((o) => request (client, completed [1]));
2435
2436                                 if (!WaitHandle.WaitAll (completed, 10000))
2437                                         Assert.Fail ("Test hung.");
2438                         }
2439                 }
2440
2441                 [Test]
2442 #if FEATURE_NO_BSD_SOCKETS
2443                 [ExpectedException (typeof (PlatformNotSupportedException))]
2444 #else
2445                 [ExpectedException (typeof (ArgumentNullException))]
2446 #endif
2447                 public void NullHost ()
2448                 {
2449                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2450                         req.Host = null;
2451                 }
2452
2453                 [Test]
2454 #if FEATURE_NO_BSD_SOCKETS
2455                 [ExpectedException (typeof (PlatformNotSupportedException))]
2456 #endif
2457                 public void NoHost ()
2458                 {
2459                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2460                         Assert.AreEqual (req.Host, "go-mono.com");
2461                 }
2462
2463                 [Test]
2464 #if FEATURE_NO_BSD_SOCKETS
2465                 [ExpectedException (typeof (PlatformNotSupportedException))]
2466 #else
2467                 [ExpectedException (typeof (ArgumentException))]
2468 #endif
2469                 public void EmptyHost ()
2470                 {
2471                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2472                         req.Host = "";
2473                 }
2474
2475                 [Test]
2476 #if FEATURE_NO_BSD_SOCKETS
2477                 [ExpectedException (typeof (PlatformNotSupportedException))]
2478 #endif
2479                 public void HostAndPort ()
2480                 {
2481                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com:80");
2482                         Assert.AreEqual ("go-mono.com", req.Host, "#01");
2483                         req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com:9000");
2484                         Assert.AreEqual ("go-mono.com:9000", req.Host, "#02");
2485                 }
2486
2487                 [Test]
2488 #if FEATURE_NO_BSD_SOCKETS
2489                 [ExpectedException (typeof (PlatformNotSupportedException))]
2490 #endif
2491                 public void PortRange ()
2492                 {
2493                         for (int i = 0; i < 65536; i++) {
2494                                 if (i == 80)
2495                                         continue;
2496                                 string s = i.ToString ();
2497                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com:" + s);
2498                                 Assert.AreEqual ("go-mono.com:" + s, req.Host, "#" + s);
2499                         }
2500                 }
2501
2502                 [Test]
2503 #if FEATURE_NO_BSD_SOCKETS
2504                 [ExpectedException (typeof (PlatformNotSupportedException))]
2505 #else
2506                 [ExpectedException (typeof (ArgumentException))]
2507 #endif
2508                 public void PortBelow ()
2509                 {
2510                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2511                         req.Host = "go-mono.com:-1";
2512                 }
2513
2514                 [Test]
2515 #if FEATURE_NO_BSD_SOCKETS
2516                 [ExpectedException (typeof (PlatformNotSupportedException))]
2517 #else
2518                 [ExpectedException (typeof (ArgumentException))]
2519 #endif
2520                 public void PortAbove ()
2521                 {
2522                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2523                         req.Host = "go-mono.com:65536";
2524                 }
2525
2526                 [Test]
2527 #if FEATURE_NO_BSD_SOCKETS
2528                 [ExpectedException (typeof (PlatformNotSupportedException))]
2529 #else
2530                 [ExpectedException (typeof (ArgumentException))]
2531 #endif
2532                 public void HostTooLong ()
2533                 {
2534                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2535                         string s = new string ('a', 100);
2536                         req.Host = s + "." + s + "." + s + "." + s + "." + s + "." + s; // Over 255 bytes
2537                 }
2538
2539                 [Test]
2540                 [Category ("NotWorking")] // #5490
2541                 public void InvalidNamesThatWork ()
2542                 {
2543                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2544                         req.Host = "-";
2545                         req.Host = "-.-";
2546                         req.Host = "á";
2547                         req.Host = new string ('a', 64); // Should fail. Max. is 63.
2548                 }
2549
2550                 [Test]
2551 #if FEATURE_NO_BSD_SOCKETS
2552                 [ExpectedException (typeof (PlatformNotSupportedException))]
2553 #endif
2554                 public void NoDate ()
2555                 {
2556                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2557                         Assert.AreEqual (DateTime.MinValue, req.Date);
2558                 }
2559
2560                 [Test]
2561 #if FEATURE_NO_BSD_SOCKETS
2562                 [ExpectedException (typeof (PlatformNotSupportedException))]
2563 #endif
2564                 public void UtcDate ()
2565                 {
2566                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2567                         req.Date = DateTime.UtcNow;
2568                         DateTime date = req.Date;
2569                         Assert.AreEqual (DateTimeKind.Local, date.Kind);
2570                 }
2571
2572                 [Test]
2573 #if FEATURE_NO_BSD_SOCKETS
2574                 [ExpectedException (typeof (PlatformNotSupportedException))]
2575 #endif
2576                 public void AddAndRemoveDate ()
2577                 {
2578                         // Neil Armstrong set his foot on Moon
2579                         var landing = new DateTime (1969, 7, 21, 2, 56, 0, DateTimeKind.Utc);
2580                         Assert.AreEqual (621214377600000000, landing.Ticks);
2581                         var unspecified = new DateTime (1969, 7, 21, 2, 56, 0);
2582                         var local = landing.ToLocalTime ();
2583
2584                         var req = (HttpWebRequest)WebRequest.Create ("http://www.mono-project.com/");
2585                         req.Date = landing;
2586                         Assert.AreEqual (DateTimeKind.Local, req.Date.Kind);
2587                         Assert.AreEqual (local.Ticks, req.Date.Ticks);
2588                         Assert.AreEqual (local, req.Date);
2589
2590                         req.Date = unspecified;
2591                         Assert.AreEqual (DateTimeKind.Local, req.Date.Kind);
2592                         Assert.AreEqual (unspecified.Ticks, req.Date.Ticks);
2593                         Assert.AreEqual (unspecified, req.Date);
2594
2595                         req.Date = local;
2596                         Assert.AreEqual (DateTimeKind.Local, req.Date.Kind);
2597                         Assert.AreEqual (local.Ticks, req.Date.Ticks);
2598                         Assert.AreEqual (local, req.Date);
2599
2600                         req.Date = DateTime.MinValue;
2601                         Assert.AreEqual (DateTimeKind.Unspecified, DateTime.MinValue.Kind);
2602                         Assert.AreEqual (DateTimeKind.Unspecified, req.Date.Kind);
2603                         Assert.AreEqual (0, req.Date.Ticks);
2604
2605                         Assert.AreEqual (null, req.Headers.Get ("Date"));
2606                 }
2607                 
2608                 [Test]
2609 #if FEATURE_NO_BSD_SOCKETS
2610                 [ExpectedException (typeof (PlatformNotSupportedException))]
2611 #endif
2612                 // Bug #12393
2613                 public void TestIPv6Host ()
2614                 {
2615                         var address = "2001:0000:0000:0001:0001:0001:0157:0000";
2616                         var address2 = '[' + address + ']';
2617                         var uri = new Uri (string.Format ("http://{0}/test.css", address2));
2618                         var hwr = (HttpWebRequest)WebRequest.Create (uri);
2619
2620                         hwr.Host = address2;
2621                         Assert.AreEqual (address2, hwr.Host, "#1");
2622                 }
2623
2624                 [Test]
2625                 // Bug #12393
2626                 [Category ("NotWorking")]
2627                 public void TestIPv6Host2 ()
2628                 {
2629                         var address = "2001:0000:0000:0001:0001:0001:0157:0000";
2630                         var address2 = '[' + address + ']';
2631                         var uri = new Uri (string.Format ("http://{0}/test.css", address2));
2632                         var hwr = (HttpWebRequest)WebRequest.Create (uri);
2633
2634                         try {
2635                                 hwr.Host = address;
2636                                 Assert.Fail ("#1");
2637                         } catch (ArgumentException) {
2638                                 ;
2639                         }
2640                 }
2641
2642                 [Test]
2643 #if FEATURE_NO_BSD_SOCKETS
2644                 [ExpectedException (typeof (PlatformNotSupportedException))]
2645 #endif
2646                 public void AllowReadStreamBuffering ()
2647                 {
2648                         var hr = WebRequest.CreateHttp ("http://www.google.com");
2649                         Assert.IsFalse (hr.AllowReadStreamBuffering, "#1");
2650                         try {
2651                                 hr.AllowReadStreamBuffering = true;
2652                                 Assert.Fail ("#2");
2653                         } catch (InvalidOperationException) {
2654                         }
2655                 }
2656
2657                 class ListenerScope : IDisposable {
2658                         EventWaitHandle completed;
2659                         public HttpListener listener;
2660                         Action<HttpListenerContext> processor;
2661
2662                         public ListenerScope (Action<HttpListenerContext> processor, int port, EventWaitHandle completed)
2663                         {
2664                                 this.processor = processor;
2665                                 this.completed = completed;
2666
2667                                 this.listener = new HttpListener ();
2668                                 this.listener.Prefixes.Add (string.Format ("http://localhost:{0}/", port));
2669                                 this.listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
2670                                 this.listener.Start ();
2671
2672                                 this.listener.BeginGetContext (this.RequestHandler, null);
2673                         }
2674
2675                         void RequestHandler (IAsyncResult result)
2676                         {
2677                                 HttpListenerContext context = null;
2678
2679                                 try {
2680                                         context = this.listener.EndGetContext (result);
2681                                 } catch (HttpListenerException ex) {
2682                                         // check if the thread has been aborted as in the case when we are shutting down.
2683                                         if (ex.ErrorCode == 995)
2684                                                 return;
2685                                 } catch (ObjectDisposedException) {
2686                                         return;
2687                                 }
2688
2689                                 ThreadPool.QueueUserWorkItem ((o) =>
2690                                 {
2691                                         try {
2692                                                 this.processor (context);
2693                                         } catch (HttpListenerException) {
2694                                         }
2695                                 });
2696
2697                                 this.completed.Set ();
2698                         }
2699
2700                         public void Dispose ()
2701                         {
2702                                 this.listener.Stop ();
2703                         }
2704                 }
2705
2706 #if !MOBILE
2707                 class SslHttpServer : HttpServer {
2708                         X509Certificate _certificate;
2709
2710                         protected override void Run ()
2711                         {
2712                                 try {
2713                                         Socket client = sock.Accept ();
2714                                         NetworkStream ns = new NetworkStream (client, true);
2715                                         SslServerStream s = new SslServerStream (ns, Certificate, false, false);
2716                                         s.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback (GetPrivateKey);
2717
2718                                         StreamReader reader = new StreamReader (s);
2719                                         StreamWriter writer = new StreamWriter (s, Encoding.ASCII);
2720
2721                                         string line;
2722                                         string hello = "<html><body><h1>Hello World!</h1></body></html>";
2723                                         string answer = "HTTP/1.0 200\r\n" +
2724                                                         "Connection: close\r\n" +
2725                                                         "Content-Type: text/html\r\n" +
2726                                                         "Content-Encoding: " + Encoding.ASCII.WebName + "\r\n" +
2727                                                         "Content-Length: " + hello.Length + "\r\n" +
2728                                                         "\r\n" + hello;
2729
2730                                         // Read the headers
2731                                         do {
2732                                                 line = reader.ReadLine ();
2733                                         } while (line != "" && line != null && line.Length > 0);
2734
2735                                         // Now the content. We know it's 100 bytes.
2736                                         // This makes BeginRead in sslclientstream block.
2737                                         char [] cs = new char [100];
2738                                         reader.Read (cs, 0, 100);
2739
2740                                         writer.Write (answer);
2741                                         writer.Flush ();
2742                                         if (evt.WaitOne (5000, false))
2743                                                 error = new Exception ("Timeout when stopping the server");
2744                                 } catch (Exception e) {
2745                                         error = e;
2746                                 }
2747                         }
2748
2749                         X509Certificate Certificate {
2750                                 get {
2751                                         if (_certificate == null)
2752                                                 _certificate = new X509Certificate (CertData.Certificate);
2753
2754                                         return _certificate;
2755                                 }
2756                         }
2757
2758                         AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
2759                         {
2760                                 PrivateKey key = new PrivateKey (CertData.PrivateKey, null);
2761                                 return key.RSA;
2762                         }
2763                 }
2764
2765                 class CertData {
2766                         public readonly static byte [] Certificate = {
2767                                 48, 130, 1, 191, 48, 130, 1, 40, 160, 3, 2, 1, 2, 2, 16, 36, 
2768                                 14, 97, 190, 146, 132, 208, 71, 175, 6, 87, 168, 185, 175, 55, 43, 48, 
2769                                 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 18, 
2770                                 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 111, 110, 122, 97, 
2771                                 108, 111, 48, 30, 23, 13, 48, 53, 48, 54, 50, 50, 49, 57, 51, 48, 
2772                                 52, 54, 90, 23, 13, 51, 57, 49, 50, 51, 49, 50, 51, 53, 57, 53, 
2773                                 57, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 
2774                                 111, 110, 122, 97, 108, 111, 48, 129, 158, 48, 13, 6, 9, 42, 134, 72, 
2775                                 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 140, 0, 48, 129, 136, 2, 
2776                                 129, 129, 0, 138, 9, 38, 25, 166, 252, 59, 26, 39, 184, 128, 216, 38, 
2777                                 73, 41, 86, 30, 228, 160, 205, 41, 135, 115, 223, 44, 62, 42, 198, 178, 
2778                                 190, 81, 11, 25, 21, 216, 49, 179, 130, 246, 52, 97, 175, 212, 94, 157, 
2779                                 231, 162, 66, 161, 103, 63, 204, 83, 141, 172, 119, 97, 225, 206, 98, 101, 
2780                                 210, 106, 2, 206, 81, 90, 173, 47, 41, 199, 209, 241, 177, 177, 96, 207, 
2781                                 254, 220, 190, 66, 180, 153, 0, 209, 14, 178, 69, 194, 3, 37, 116, 239, 
2782                                 49, 23, 185, 245, 255, 126, 35, 85, 246, 56, 244, 107, 117, 24, 14, 57, 
2783                                 9, 111, 147, 189, 220, 142, 57, 104, 153, 193, 205, 19, 14, 22, 157, 16, 
2784                                 24, 80, 201, 2, 2, 0, 17, 163, 23, 48, 21, 48, 19, 6, 3, 85, 
2785                                 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 
2786                                 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3, 
2787                                 129, 129, 0, 64, 49, 57, 253, 218, 198, 229, 51, 189, 12, 154, 225, 183, 
2788                                 160, 147, 90, 113, 172, 69, 122, 28, 77, 97, 215, 231, 194, 150, 29, 196, 
2789                                 65, 95, 218, 99, 142, 111, 79, 205, 109, 76, 32, 92, 220, 76, 88, 53, 
2790                                 237, 80, 11, 85, 44, 91, 21, 210, 12, 34, 223, 234, 18, 187, 136, 62, 
2791                                 26, 240, 103, 180, 12, 226, 221, 250, 247, 129, 51, 23, 129, 165, 56, 67, 
2792                                 43, 83, 244, 110, 207, 24, 253, 195, 16, 46, 80, 113, 80, 18, 2, 254, 
2793                                 120, 147, 151, 164, 23, 210, 230, 100, 19, 197, 179, 28, 194, 48, 106, 159, 
2794                                 155, 144, 37, 82, 44, 160, 40, 52, 146, 174, 77, 188, 160, 230, 75, 172, 
2795                                 123, 3, 254, 
2796                         };
2797
2798                         public readonly static byte [] PrivateKey = {
2799                                 30, 241, 181, 176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 
2800                                 0, 0, 0, 0, 84, 2, 0, 0, 7, 2, 0, 0, 0, 36, 0, 0, 
2801                                 82, 83, 65, 50, 0, 4, 0, 0, 17, 0, 0, 0, 201, 80, 24, 16, 
2802                                 157, 22, 14, 19, 205, 193, 153, 104, 57, 142, 220, 189, 147, 111, 9, 57, 
2803                                 14, 24, 117, 107, 244, 56, 246, 85, 35, 126, 255, 245, 185, 23, 49, 239, 
2804                                 116, 37, 3, 194, 69, 178, 14, 209, 0, 153, 180, 66, 190, 220, 254, 207, 
2805                                 96, 177, 177, 241, 209, 199, 41, 47, 173, 90, 81, 206, 2, 106, 210, 101, 
2806                                 98, 206, 225, 97, 119, 172, 141, 83, 204, 63, 103, 161, 66, 162, 231, 157, 
2807                                 94, 212, 175, 97, 52, 246, 130, 179, 49, 216, 21, 25, 11, 81, 190, 178, 
2808                                 198, 42, 62, 44, 223, 115, 135, 41, 205, 160, 228, 30, 86, 41, 73, 38, 
2809                                 216, 128, 184, 39, 26, 59, 252, 166, 25, 38, 9, 138, 175, 88, 190, 223, 
2810                                 27, 24, 224, 123, 190, 69, 164, 234, 129, 59, 108, 229, 248, 62, 187, 15, 
2811                                 235, 147, 162, 83, 47, 123, 170, 190, 224, 31, 215, 110, 143, 31, 227, 216, 
2812                                 85, 88, 154, 83, 207, 229, 41, 28, 237, 116, 181, 17, 37, 141, 224, 185, 
2813                                 164, 144, 141, 233, 164, 138, 177, 241, 115, 181, 230, 150, 7, 92, 139, 141, 
2814                                 113, 95, 57, 191, 211, 165, 217, 250, 197, 68, 164, 184, 168, 43, 48, 65, 
2815                                 177, 237, 173, 144, 148, 221, 62, 189, 147, 63, 216, 188, 206, 103, 226, 171, 
2816                                 32, 20, 230, 116, 144, 192, 1, 39, 202, 87, 74, 250, 6, 142, 188, 23, 
2817                                 45, 4, 112, 191, 253, 67, 69, 70, 128, 143, 44, 234, 41, 96, 195, 82, 
2818                                 202, 35, 158, 149, 240, 151, 23, 25, 166, 179, 85, 144, 58, 120, 149, 229, 
2819                                 205, 34, 8, 110, 86, 119, 130, 210, 37, 173, 65, 71, 169, 67, 8, 51, 
2820                                 20, 96, 51, 155, 3, 39, 85, 187, 40, 193, 57, 19, 99, 78, 173, 28, 
2821                                 129, 154, 108, 175, 8, 138, 237, 71, 27, 148, 129, 35, 47, 57, 101, 237, 
2822                                 168, 178, 227, 221, 212, 63, 124, 254, 253, 215, 183, 159, 49, 103, 74, 49, 
2823                                 67, 160, 171, 72, 194, 215, 108, 251, 178, 18, 184, 100, 211, 105, 21, 186, 
2824                                 39, 66, 218, 154, 72, 222, 90, 237, 179, 251, 51, 224, 212, 56, 251, 6, 
2825                                 209, 151, 198, 176, 89, 110, 35, 141, 248, 237, 223, 68, 135, 206, 207, 169, 
2826                                 254, 219, 243, 130, 71, 11, 94, 113, 233, 92, 63, 156, 169, 72, 215, 110, 
2827                                 95, 94, 191, 50, 59, 89, 187, 59, 183, 99, 161, 146, 233, 245, 219, 80, 
2828                                 87, 113, 251, 50, 144, 195, 158, 46, 189, 232, 119, 91, 75, 22, 6, 176, 
2829                                 39, 206, 25, 196, 213, 195, 219, 24, 28, 103, 104, 36, 137, 128, 4, 119, 
2830                                 163, 40, 126, 87, 18, 86, 128, 243, 213, 101, 2, 237, 78, 64, 160, 55, 
2831                                 199, 93, 90, 126, 175, 199, 55, 89, 234, 190, 5, 16, 196, 88, 28, 208, 
2832                                 28, 92, 32, 115, 204, 9, 202, 101, 15, 123, 43, 75, 90, 144, 95, 179, 
2833                                 102, 249, 57, 150, 204, 99, 147, 203, 16, 63, 81, 244, 226, 237, 82, 204, 
2834                                 20, 200, 140, 65, 83, 217, 161, 23, 123, 37, 115, 12, 100, 73, 70, 190, 
2835                                 32, 235, 174, 140, 148, 157, 47, 238, 40, 208, 228, 80, 54, 187, 156, 252, 
2836                                 253, 230, 231, 156, 138, 125, 96, 79, 3, 27, 143, 55, 146, 169, 165, 61, 
2837                                 238, 60, 227, 77, 217, 93, 117, 122, 111, 46, 173, 113, 
2838                         };
2839                 }
2840 #endif
2841
2842                 [Test]
2843 #if FEATURE_NO_BSD_SOCKETS
2844                 [ExpectedException (typeof (PlatformNotSupportedException))]
2845 #endif
2846                 public void CookieContainerTest ()
2847                 {
2848                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2849                         string url = "http://" + ep.ToString ();
2850
2851                         using (SocketResponder responder = new SocketResponder (ep, s => CookieRequestHandler (s))) {
2852                                 CookieContainer container = new CookieContainer ();
2853                                 container.Add(new Uri (url), new Cookie ("foo", "bar"));
2854                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
2855                                 request.CookieContainer = container;
2856                                 WebHeaderCollection headers = request.Headers;
2857                                 headers.Add("Cookie", "foo=baz");
2858                                 HttpWebResponse response = (HttpWebResponse) request.GetResponse ();
2859                                 string responseString = null;
2860                                 using (StreamReader reader = new StreamReader (response.GetResponseStream ())) {
2861                                         responseString = reader.ReadToEnd ();
2862                                 }
2863                                 response.Close ();
2864                                 Assert.AreEqual (1, response.Cookies.Count, "#01");
2865                                 Assert.AreEqual ("foo=bar", response.Headers.Get("Set-Cookie"), "#02");
2866                         }
2867
2868                         using (SocketResponder responder = new SocketResponder (ep, s => CookieRequestHandler (s))) {
2869                                 CookieContainer container = new CookieContainer ();
2870                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
2871                                 request.CookieContainer = container;
2872                                 WebHeaderCollection headers = request.Headers;
2873                                 headers.Add("Cookie", "foo=baz");
2874                                 HttpWebResponse response = (HttpWebResponse) request.GetResponse ();
2875                                 string responseString = null;
2876                                 using (StreamReader reader = new StreamReader (response.GetResponseStream ())) {
2877                                         responseString = reader.ReadToEnd ();
2878                                 }
2879                                 response.Close ();
2880                                 Assert.AreEqual (0, response.Cookies.Count, "#03");
2881                                 Assert.AreEqual ("", response.Headers.Get("Set-Cookie"), "#04");
2882                         }
2883                 }
2884
2885                 internal static byte[] CookieRequestHandler (Socket socket)
2886                 {
2887                         MemoryStream ms = new MemoryStream ();
2888                         byte[] buffer = new byte[4096];
2889                         int bytesReceived = socket.Receive (buffer);
2890                         while (bytesReceived > 0) {
2891                                 ms.Write(buffer, 0, bytesReceived);
2892                                 // We don't check for Content-Length or anything else here, so we give the client a little time to write
2893                                 // after sending the headers
2894                                 Thread.Sleep(200);
2895                                 if (socket.Available > 0) {
2896                                         bytesReceived = socket.Receive (buffer);
2897                                 } else {
2898                                         bytesReceived = 0;
2899                                 }
2900                         }
2901                         ms.Flush();
2902                         ms.Position = 0;
2903                         string cookies = string.Empty;
2904                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
2905                                 string line;
2906                                 while ((line = sr.ReadLine ()) != null) {
2907                                         if (line.StartsWith ("Cookie:")) {
2908                                                 cookies = line.Substring ("cookie: ".Length);
2909                                         }
2910                                 }
2911                         }
2912
2913                         StringWriter sw = new StringWriter ();
2914                         sw.WriteLine ("HTTP/1.1 200 OK");
2915                         sw.WriteLine ("Content-Type: text/xml");
2916                         sw.WriteLine ("Set-Cookie: " + cookies);
2917                         sw.WriteLine ("Content-Length: " + cookies.Length.ToString (CultureInfo.InvariantCulture));
2918                         sw.WriteLine ();
2919                         sw.Write (cookies);
2920                         sw.Flush ();
2921
2922                         return Encoding.UTF8.GetBytes (sw.ToString ());
2923                 }
2924         }
2925
2926         [TestFixture]
2927         public class HttpRequestStreamTest
2928         {
2929                 [Test]
2930 #if FEATURE_NO_BSD_SOCKETS
2931                 [ExpectedException (typeof (PlatformNotSupportedException))]
2932 #endif
2933                 public void BeginRead ()
2934                 {
2935                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2936                         string url = "http://" + ep.ToString () + "/test/";
2937
2938                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2939                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2940                                 req.Method = "POST";
2941
2942                                 using (Stream rs = req.GetRequestStream ()) {
2943                                         byte [] buffer = new byte [10];
2944                                         try {
2945                                                 rs.BeginRead (buffer, 0, buffer.Length, null, null);
2946                                                 Assert.Fail ("#1");
2947                                         } catch (NotSupportedException ex) {
2948                                                 // The stream does not support reading
2949                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
2950                                                 Assert.IsNull (ex.InnerException, "#3");
2951                                                 Assert.IsNotNull (ex.Message, "#4");
2952                                         } finally {
2953                                                 req.Abort ();
2954                                         }
2955                                 }
2956                         }
2957                 }
2958
2959                 [Test]
2960                 [Category("MobileNotWorking")]
2961                 public void BeginWrite_Request_Aborted ()
2962                 {
2963                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2964                         string url = "http://" + ep.ToString () + "/test/";
2965
2966                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2967                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2968                                 req.Method = "POST";
2969
2970                                 using (Stream rs = req.GetRequestStream ()) {
2971                                         req.Abort ();
2972                                         try {
2973                                                 rs.BeginWrite (new byte [] { 0x2a, 0x2f }, 0, 2, null, null);
2974                                                 Assert.Fail ("#1");
2975                                         } catch (WebException ex) {
2976                                                 // The request was aborted: The request was canceled
2977                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
2978                                                 Assert.IsNull (ex.InnerException, "#3");
2979                                                 Assert.IsNotNull (ex.Message, "#4");
2980                                                 Assert.IsNull (ex.Response, "#5");
2981                                                 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
2982                                         }
2983                                 }
2984                         }
2985                 }
2986
2987                 [Test]
2988 #if FEATURE_NO_BSD_SOCKETS
2989                 [ExpectedException (typeof (PlatformNotSupportedException))]
2990 #endif
2991                 public void CanRead ()
2992                 {
2993                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2994                         string url = "http://" + ep.ToString () + "/test/";
2995
2996                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2997                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2998                                 req.Method = "POST";
2999
3000                                 Stream rs = req.GetRequestStream ();
3001                                 try {
3002                                         Assert.IsFalse (rs.CanRead, "#1");
3003                                         rs.Close ();
3004                                         Assert.IsFalse (rs.CanRead, "#2");
3005                                 } finally {
3006                                         rs.Close ();
3007                                         req.Abort ();
3008                                 }
3009                         }
3010                 }
3011
3012                 [Test]
3013 #if FEATURE_NO_BSD_SOCKETS
3014                 [ExpectedException (typeof (PlatformNotSupportedException))]
3015 #endif
3016                 public void CanSeek ()
3017                 {
3018                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3019                         string url = "http://" + ep.ToString () + "/test/";
3020
3021                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3022                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3023                                 req.Method = "POST";
3024
3025                                 Stream rs = req.GetRequestStream ();
3026                                 try {
3027                                         Assert.IsFalse (rs.CanSeek, "#1");
3028                                         rs.Close ();
3029                                         Assert.IsFalse (rs.CanSeek, "#2");
3030                                 } finally {
3031                                         rs.Close ();
3032                                         req.Abort ();
3033                                 }
3034                         }
3035                 }
3036
3037                 [Test] // bug #324182
3038 #if FEATURE_NO_BSD_SOCKETS
3039                 [ExpectedException (typeof (PlatformNotSupportedException))]
3040 #endif
3041                 public void CanTimeout ()
3042                 {
3043                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3044                         string url = "http://" + ep.ToString () + "/test/";
3045
3046                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3047                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3048                                 req.Method = "POST";
3049
3050                                 Stream rs = req.GetRequestStream ();
3051                                 try {
3052                                         Assert.IsTrue (rs.CanTimeout, "#1");
3053                                         rs.Close ();
3054                                         Assert.IsTrue (rs.CanTimeout, "#2");
3055                                 } finally {
3056                                         rs.Close ();
3057                                         req.Abort ();
3058                                 }
3059                         }
3060                 }
3061
3062                 [Test]
3063 #if FEATURE_NO_BSD_SOCKETS
3064                 [ExpectedException (typeof (PlatformNotSupportedException))]
3065 #endif
3066                 public void CanWrite ()
3067                 {
3068                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3069                         string url = "http://" + ep.ToString () + "/test/";
3070
3071                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3072                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3073                                 req.Method = "POST";
3074
3075                                 Stream rs = req.GetRequestStream ();
3076                                 try {
3077                                         Assert.IsTrue (rs.CanWrite, "#1");
3078                                         rs.Close ();
3079                                         Assert.IsFalse (rs.CanWrite, "#2");
3080                                 } finally {
3081                                         rs.Close ();
3082                                         req.Abort ();
3083                                 }
3084                         }
3085                 }
3086
3087                 [Test]
3088 #if FEATURE_NO_BSD_SOCKETS
3089                 [ExpectedException (typeof (PlatformNotSupportedException))]
3090 #endif
3091                 public void Read ()
3092                 {
3093                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3094                         string url = "http://" + ep.ToString () + "/test/";
3095
3096                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3097                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3098                                 req.Method = "POST";
3099
3100                                 using (Stream rs = req.GetRequestStream ()) {
3101                                         byte [] buffer = new byte [10];
3102                                         try {
3103                                                 rs.Read (buffer, 0, buffer.Length);
3104                                                 Assert.Fail ("#1");
3105                                         } catch (NotSupportedException ex) {
3106                                                 // The stream does not support reading
3107                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
3108                                                 Assert.IsNull (ex.InnerException, "#3");
3109                                                 Assert.IsNotNull (ex.Message, "#4");
3110                                         } finally {
3111                                                 req.Abort ();
3112                                         }
3113                                 }
3114                         }
3115                 }
3116
3117                 [Test]
3118 #if FEATURE_NO_BSD_SOCKETS
3119                 [ExpectedException (typeof (PlatformNotSupportedException))]
3120 #endif
3121                 public void ReadByte ()
3122                 {
3123                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3124                         string url = "http://" + ep.ToString () + "/test/";
3125
3126                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3127                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3128                                 req.Method = "POST";
3129
3130                                 using (Stream rs = req.GetRequestStream ()) {
3131                                         try {
3132                                                 rs.ReadByte ();
3133                                                 Assert.Fail ("#1");
3134                                         } catch (NotSupportedException ex) {
3135                                                 // The stream does not support reading
3136                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
3137                                                 Assert.IsNull (ex.InnerException, "#3");
3138                                                 Assert.IsNotNull (ex.Message, "#4");
3139                                         } finally {
3140                                                 req.Abort ();
3141                                         }
3142                                 }
3143                         }
3144                 }
3145
3146                 [Test]
3147 #if FEATURE_NO_BSD_SOCKETS
3148                 [ExpectedException (typeof (PlatformNotSupportedException))]
3149 #endif
3150                 public void ReadTimeout ()
3151                 {
3152                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3153                         string url = "http://" + ep.ToString () + "/test/";
3154
3155                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3156                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3157                                 req.Method = "POST";
3158
3159                                 Stream rs = req.GetRequestStream ();
3160                                 try {
3161                                         Assert.AreEqual (300000, rs.ReadTimeout, "#1");
3162                                         rs.Close ();
3163                                         Assert.AreEqual (300000, rs.ReadTimeout, "#2");
3164                                 } finally {
3165                                         rs.Close ();
3166                                         req.Abort ();
3167                                 }
3168                         }
3169                 }
3170
3171                 [Test]
3172 #if FEATURE_NO_BSD_SOCKETS
3173                 [ExpectedException (typeof (PlatformNotSupportedException))]
3174 #endif
3175                 public void Seek ()
3176                 {
3177                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3178                         string url = "http://" + ep.ToString () + "/test/";
3179
3180                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3181                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3182                                 req.Method = "POST";
3183
3184                                 using (Stream rs = req.GetRequestStream ()) {
3185                                         try {
3186                                                 rs.Seek (0, SeekOrigin.Current);
3187                                                 Assert.Fail ("#1");
3188                                         } catch (NotSupportedException ex) {
3189                                                 // This stream does not support seek operations
3190                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
3191                                                 Assert.IsNull (ex.InnerException, "#3");
3192                                                 Assert.IsNotNull (ex.Message, "#4");
3193                                         } finally {
3194                                                 req.Abort ();
3195                                         }
3196                                 }
3197                         }
3198                 }
3199
3200                 [Test]
3201 #if FEATURE_NO_BSD_SOCKETS
3202                 [ExpectedException (typeof (PlatformNotSupportedException))]
3203 #endif
3204                 public void Write_Buffer_Null ()
3205                 {
3206                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3207                         string url = "http://" + ep.ToString () + "/test/";
3208
3209                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3210                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3211                                 req.Method = "POST";
3212
3213                                 using (Stream rs = req.GetRequestStream ()) {
3214                                         try {
3215                                                 rs.Write ((byte []) null, -1, -1);
3216                                                 Assert.Fail ("#1");
3217                                         } catch (ArgumentNullException ex) {
3218                                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
3219                                                 Assert.IsNull (ex.InnerException, "#3");
3220                                                 Assert.IsNotNull (ex.Message, "#4");
3221                                                 Assert.AreEqual ("buffer", ex.ParamName, "#5");
3222                                         }
3223                                 }
3224
3225                                 req.Abort ();
3226                         }
3227                 }
3228
3229                 [Test]
3230 #if FEATURE_NO_BSD_SOCKETS
3231                 [ExpectedException (typeof (PlatformNotSupportedException))]
3232 #endif
3233                 public void Write_Count_Negative ()
3234                 {
3235                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3236                         string url = "http://" + ep.ToString () + "/test/";
3237
3238                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3239                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3240                                 req.Method = "POST";
3241
3242                                 using (Stream rs = req.GetRequestStream ()) {
3243                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3244                                         try {
3245                                                 rs.Write (buffer, 1, -1);
3246                                                 Assert.Fail ("#1");
3247                                         } catch (ArgumentOutOfRangeException ex) {
3248                                                 // Specified argument was out of the range of valid values
3249                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
3250                                                 Assert.IsNull (ex.InnerException, "#A3");
3251                                                 Assert.IsNotNull (ex.Message, "#A4");
3252                                                 Assert.AreEqual ("size", ex.ParamName, "#A5");
3253                                         }
3254                                 }
3255
3256                                 req.Abort ();
3257                         }
3258                 }
3259
3260                 [Test]
3261 #if FEATURE_NO_BSD_SOCKETS
3262                 [ExpectedException (typeof (PlatformNotSupportedException))]
3263 #endif
3264                 public void Write_Count_Overflow ()
3265                 {
3266                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3267                         string url = "http://" + ep.ToString () + "/test/";
3268
3269                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3270                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3271                                 req.Method = "POST";
3272
3273                                 using (Stream rs = req.GetRequestStream ()) {
3274                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3275                                         try {
3276                                                 rs.Write (buffer, buffer.Length - 2, 3);
3277                                                 Assert.Fail ("#1");
3278                                         } catch (ArgumentOutOfRangeException ex) {
3279                                                 // Specified argument was out of the range of valid values
3280                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
3281                                                 Assert.IsNull (ex.InnerException, "#3");
3282                                                 Assert.IsNotNull (ex.Message, "#4");
3283                                                 Assert.AreEqual ("size", ex.ParamName, "#5");
3284                                         }
3285                                 }
3286
3287                                 req.Abort ();
3288                         }
3289                 }
3290
3291                 [Test]
3292 #if FEATURE_NO_BSD_SOCKETS
3293                 [ExpectedException (typeof (PlatformNotSupportedException))]
3294 #endif
3295                 public void Write_Offset_Negative ()
3296                 {
3297                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3298                         string url = "http://" + ep.ToString () + "/test/";
3299
3300                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3301                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3302                                 req.Method = "POST";
3303
3304                                 using (Stream rs = req.GetRequestStream ()) {
3305                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3306                                         try {
3307                                                 rs.Write (buffer, -1, 0);
3308                                                 Assert.Fail ("#1");
3309                                         } catch (ArgumentOutOfRangeException ex) {
3310                                                 // Specified argument was out of the range of valid values
3311                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
3312                                                 Assert.IsNull (ex.InnerException, "#3");
3313                                                 Assert.IsNotNull (ex.Message, "#4");
3314                                                 Assert.AreEqual ("offset", ex.ParamName, "#5");
3315                                         }
3316                                 }
3317
3318                                 req.Abort ();
3319                         }
3320                 }
3321
3322                 [Test]
3323 #if FEATURE_NO_BSD_SOCKETS
3324                 [ExpectedException (typeof (PlatformNotSupportedException))]
3325 #endif
3326                 public void Write_Offset_Overflow ()
3327                 {
3328                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3329                         string url = "http://" + ep.ToString () + "/test/";
3330
3331                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3332                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3333                                 req.Method = "POST";
3334
3335                                 using (Stream rs = req.GetRequestStream ()) {
3336                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3337                                         try {
3338                                                 rs.Write (buffer, buffer.Length + 1, 0);
3339                                                 Assert.Fail ("#1");
3340                                         } catch (ArgumentOutOfRangeException ex) {
3341                                                 // Specified argument was out of the range of valid values
3342                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
3343                                                 Assert.IsNull (ex.InnerException, "#3");
3344                                                 Assert.IsNotNull (ex.Message, "#4");
3345                                                 Assert.AreEqual ("offset", ex.ParamName, "#5");
3346                                         }
3347                                 }
3348
3349                                 req.Abort ();
3350                         }
3351                 }
3352
3353                 [Test]
3354 #if FEATURE_NO_BSD_SOCKETS
3355                 [ExpectedException (typeof (PlatformNotSupportedException))]
3356 #endif
3357                 public void Write_Request_Aborted ()
3358                 {
3359                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3360                         string url = "http://" + ep.ToString () + "/test/";
3361
3362                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3363                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3364                                 req.Method = "POST";
3365
3366                                 using (Stream rs = req.GetRequestStream ()) {
3367                                         req.Abort ();
3368                                         try {
3369                                                 rs.Write (new byte [0], 0, 0);
3370                                                 Assert.Fail ("#1");
3371                                         } catch (WebException ex) {
3372                                                 // The request was aborted: The request was canceled
3373                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
3374                                                 Assert.IsNull (ex.InnerException, "#3");
3375                                                 Assert.IsNotNull (ex.Message, "#4");
3376                                                 Assert.IsNull (ex.Response, "#5");
3377                                                 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
3378                                         }
3379                                 }
3380                         }
3381                 }
3382
3383                 [Test]
3384                 [Category ("NotWorking")]
3385                 public void Write_Stream_Closed ()
3386                 {
3387                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3388                         string url = "http://" + ep.ToString () + "/test/";
3389
3390                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3391                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3392                                 req.Method = "POST";
3393
3394                                 using (Stream rs = req.GetRequestStream ()) {
3395                                         rs.Close ();
3396                                         try {
3397                                                 rs.Write (new byte [0], 0, 0);
3398                                                 Assert.Fail ("#1");
3399                                         } catch (WebException ex) {
3400                                                 // The request was aborted: The connection was closed unexpectedly
3401                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
3402                                                 Assert.IsNull (ex.InnerException, "#3");
3403                                                 Assert.IsNotNull (ex.Message, "#4");
3404                                                 Assert.IsNull (ex.Response, "#5");
3405                                                 Assert.AreEqual (WebExceptionStatus.ConnectionClosed, ex.Status, "#6");
3406                                         }
3407                                 }
3408                         }
3409                 }
3410
3411                 [Test]
3412 #if FEATURE_NO_BSD_SOCKETS
3413                 [ExpectedException (typeof (PlatformNotSupportedException))]
3414 #endif
3415                 public void WriteByte_Request_Aborted ()
3416                 {
3417                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3418                         string url = "http://" + ep.ToString () + "/test/";
3419
3420                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3421                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3422                                 req.Method = "POST";
3423
3424                                 using (Stream rs = req.GetRequestStream ()) {
3425                                         req.Abort ();
3426                                         try {
3427                                                 rs.WriteByte (0x2a);
3428                                                 Assert.Fail ("#1");
3429                                         } catch (WebException ex) {
3430                                                 // The request was aborted: The request was canceled
3431                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
3432                                                 Assert.IsNull (ex.InnerException, "#3");
3433                                                 Assert.IsNotNull (ex.Message, "#4");
3434                                                 Assert.IsNull (ex.Response, "#5");
3435                                                 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
3436                                         }
3437                                 }
3438                         }
3439                 }
3440
3441                 [Test]
3442 #if FEATURE_NO_BSD_SOCKETS
3443                 [ExpectedException (typeof (PlatformNotSupportedException))]
3444 #endif
3445                 public void WriteTimeout ()
3446                 {
3447                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3448                         string url = "http://" + ep.ToString () + "/test/";
3449
3450                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3451                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3452                                 req.Method = "POST";
3453
3454                                 Stream rs = req.GetRequestStream ();
3455                                 try {
3456                                         Assert.AreEqual (300000, rs.WriteTimeout, "#1");
3457                                         rs.Close ();
3458                                         Assert.AreEqual (300000, rs.WriteTimeout, "#2");
3459                                 } finally {
3460                                         rs.Close ();
3461                                         req.Abort ();
3462                                 }
3463                         }
3464                 }
3465
3466                 [Test]
3467 #if FEATURE_NO_BSD_SOCKETS
3468                 [ExpectedException (typeof (PlatformNotSupportedException))]
3469 #endif
3470                 // Bug6737
3471                 // This test is supposed to fail prior to .NET 4.0
3472                 public void Post_EmptyRequestStream ()
3473                 {
3474                         var wr = HttpWebRequest.Create ("http://google.com");
3475                         wr.Method = "POST";
3476                         wr.GetRequestStream ();
3477                         
3478                         var gr = wr.BeginGetResponse (delegate { }, null);
3479                         Assert.AreEqual (true, gr.AsyncWaitHandle.WaitOne (5000), "#1");
3480                 }
3481         }
3482
3483         static class StreamExtensions {
3484                 public static int ReadAll(this Stream stream, byte[] buffer, int offset, int count)
3485                 {
3486                         int totalRead = 0;
3487
3488                         while (totalRead < count) {
3489                                 int bytesRead = stream.Read (buffer, offset + totalRead, count - totalRead);
3490                                 if (bytesRead == 0)
3491                                         break;
3492
3493                                 totalRead += bytesRead;
3494                         }
3495
3496                         return totalRead;
3497                 }
3498         }
3499
3500         static class ExceptionAssert {
3501                 /// <summary>
3502                 /// Asserts that the function throws an exception.
3503                 /// </summary>
3504                 /// <param name="f">A function execute that is expected to raise an exception.</param>
3505                 /// <typeparam name="T">The type of exception that is expected.</typeparam>
3506                 /// <returns>The exception thrown.</returns>
3507                 /// <exception cref="AssertFailedException">If the function does not throw an exception 
3508                 /// or throws a different exception.</exception>
3509                 /// <example><![CDATA[
3510                 ///     ExceptionAssert.Throws(typeof(ArgumentNullException), delegate {
3511                 ///         myObject.myFunction(null); });
3512                 /// ]]></example>
3513                 public static T Throws<T> (Action f) where T : Exception {
3514                         Exception actualException = null;
3515
3516                         try {
3517                                 f ();
3518                         } catch (Exception ex) {
3519                                 actualException = ex;
3520                         }
3521
3522                         if (actualException == null)
3523                                 throw new AssertionException (string.Format (
3524                                         "No exception thrown. Expected '{0}'",
3525                                         typeof (T).FullName));
3526                         else if (typeof(T) != actualException.GetType())
3527                                 throw new AssertionException (string.Format (
3528                                         "Caught exception of type '{0}'. Expected '{1}':{2}",
3529                                         actualException.GetType().FullName,
3530                                         typeof (T).FullName,
3531                                         Environment.NewLine + actualException));
3532
3533                         return (T) actualException;
3534                 }
3535         }
3536 }