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