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