ee6c82895e3e7ae5914ca2ffb463a39cc7fdb9d8
[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: ignore\r\n" +
1722                                         "WWW-Authenticate: NTLM\r\n" +
1723                                         "WWW-Authenticate: ignore,K\r\n" +
1724                                                 "Content-Length: 5\r\n\r\nWRONG");
1725
1726                                 writer.Flush ();
1727                                 Where = "second read";
1728                                 while ((line = reader.ReadLine ()) != null) {
1729                                         if (line.Trim () == String.Empty) {
1730                                                 break;
1731                                         }
1732                                 }
1733                                 Where = "second write";
1734                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1735                                                 "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggAC8GDhqIONH3sAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=\r\n" +
1736                                                 "Content-Length: 5\r\n\r\nWRONG");
1737                                 writer.Flush ();
1738
1739                                 Where = "third read";
1740                                 while ((line = reader.ReadLine ()) != null) {
1741                                         if (line.Trim () == String.Empty) {
1742                                                 break;
1743                                         }
1744                                 }
1745                                 Where = "third write";
1746                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1747                                                 "Keep-Alive: true\r\n" +
1748                                                 "Content-Length: 2\r\n\r\nOK");
1749                                 writer.Flush ();
1750                                 Thread.Sleep (1000);
1751                                 writer.Close ();
1752                                 reader.Close ();
1753                                 client.Close ();
1754                         }
1755                 }
1756
1757                 class BadChunkedServer : HttpServer {
1758                         protected override void Run ()
1759                         {
1760                                 Socket client = sock.Accept ();
1761                                 NetworkStream ns = new NetworkStream (client, true);
1762                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1763                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1764                                                 "Transfer-Encoding: chunked\r\n" +
1765                                                 "Connection: close\r\n" +
1766                                                 "Content-Type: text/plain; charset=UTF-8\r\n\r\n");
1767
1768                                 // This body lacks a 'last-chunk' (see RFC 2616)
1769                                 writer.Write ("10\r\n1234567890123456\r\n");
1770                                 writer.Flush ();
1771                                 client.Shutdown (SocketShutdown.Send);
1772                                 Thread.Sleep (1000);
1773                                 writer.Close ();
1774                         }
1775                 }
1776
1777                 class AcceptAllPolicy : ICertificatePolicy {
1778                         public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
1779                         {
1780                                 return true;
1781                         }
1782                 }
1783
1784                 abstract class HttpServer
1785                 {
1786                         protected Socket sock;
1787                         protected Exception error;
1788                         protected ManualResetEvent evt;
1789
1790                         public HttpServer ()
1791                         {
1792                                 sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1793                                 sock.Bind (new IPEndPoint (IPAddress.Loopback, 0));
1794                                 sock.Listen (1);
1795                         }
1796
1797                         public void Start ()
1798                         {
1799                                 evt = new ManualResetEvent (false);
1800                                 Thread th = new Thread (new ThreadStart (Run));
1801                                 th.Start ();
1802                         }
1803
1804                         public void Stop ()
1805                         {
1806                                 evt.Set ();
1807                                 sock.Close ();
1808                         }
1809                         
1810                         public IPAddress IPAddress {
1811                                 get { return ((IPEndPoint) sock.LocalEndPoint).Address; }
1812                         }
1813                         
1814                         public int Port {
1815                                 get { return ((IPEndPoint) sock.LocalEndPoint).Port; }
1816                         }
1817
1818                         public Exception Error { 
1819                                 get { return error; }
1820                         }
1821
1822                         protected abstract void Run ();
1823                 }
1824
1825                 [Test]
1826                 public void BeginGetRequestStream ()
1827                 {
1828                         this.DoRequest (
1829                         (r, c) =>
1830                         {
1831                                 r.Method = "POST";
1832                                 r.ContentLength = 0;
1833                                 r.BeginGetRequestStream ((a) =>
1834                                 {
1835                                 using (Stream s = r.EndGetRequestStream (a)) { };
1836                                 c.Set();
1837                                 },
1838                                 null);
1839                         },
1840                         (c) => { });
1841                 }
1842
1843                 [Test]
1844                 public void BeginGetRequestStreamNoClose ()
1845                 {
1846                         this.DoRequest (
1847                         (r, c) => {
1848                                 r.Method = "POST";
1849                                 r.ContentLength = 1;
1850                                 r.BeginGetRequestStream ((a) =>
1851                                 {
1852                                         r.EndGetRequestStream (a);
1853                                         c.Set ();
1854                                 },
1855                                 null);
1856                         },
1857                         (c) => {});
1858                 }
1859
1860                 [Test]
1861                 public void BeginGetRequestStreamCancelIfNotAllBytesWritten ()
1862                 {
1863                         this.DoRequest (
1864                         (r, c) =>
1865                         {
1866                                 r.Method = "POST";
1867                                 r.ContentLength = 10;
1868                                 r.BeginGetRequestStream ((a) =>
1869                                 {
1870                                         WebException ex = ExceptionAssert.Throws<WebException> (() =>
1871                                         {
1872                                                 using (Stream s = r.EndGetRequestStream (a)) {
1873                                                 }
1874                                         }
1875                                 );
1876                                 Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
1877                                 c.Set();
1878                                 },
1879                                 null);
1880                         },
1881                         (c) => { });
1882                 }
1883
1884                 [Test]
1885                 public void GetRequestStream2 ()
1886                 {
1887                         this.DoRequest (
1888                         (r, c) =>
1889                         {
1890                                 r.Method = "POST";
1891                                 r.ContentLength = data64KB.Length;
1892                                 using (Stream s = r.GetRequestStream ()) {
1893                                         s.Write (data64KB, 0, data64KB.Length);
1894                                 }
1895                                 c.Set ();
1896                         },
1897                         (c) => { });
1898                 }
1899
1900                 [Test]
1901                 public void GetRequestStreamNotAllBytesWritten ()
1902                 {
1903                         this.DoRequest (
1904                         (r, c) =>
1905                         {
1906                                 r.Method = "POST";
1907                                 r.ContentLength = data64KB.Length;
1908                                 WebException ex = ExceptionAssert.Throws<WebException> (() => r.GetRequestStream ().Close ());
1909                                 Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
1910                                 c.Set ();
1911                         },
1912                         (c) => {});
1913                 }
1914
1915                 [Test]
1916                 public void GetRequestStreamTimeout ()
1917                 {
1918                         this.DoRequest (
1919                         (r, c) =>
1920                         {
1921                                 r.Method = "POST";
1922                                 r.ContentLength = data64KB.Length;
1923                                 r.Timeout = 100;
1924                                 WebException ex = ExceptionAssert.Throws<WebException> (() => r.GetRequestStream ());
1925                                 Assert.IsTrue (ex.Status == WebExceptionStatus.Timeout || ex.Status == WebExceptionStatus.ConnectFailure);
1926                                 c.Set();
1927                         });
1928                 }
1929
1930                 [Test]
1931                 public void BeginWrite ()
1932                 {
1933                         byte[] received = new byte[data64KB.Length];
1934
1935                         this.DoRequest (
1936                         (r, c) =>
1937                         {
1938                                 r.Method = "POST";
1939                                 r.ContentLength = data64KB.Length;
1940
1941                                 Stream s = r.GetRequestStream ();
1942                                 s.BeginWrite (data64KB, 0, data64KB.Length,
1943                                 (a) =>
1944                                 {
1945                                         s.EndWrite (a);
1946                                         s.Close ();
1947                                         r.GetResponse ().Close ();
1948                                         c.Set();
1949                                 },
1950                                 null);
1951                         },
1952                         (c) =>
1953                         {
1954                                 c.Request.InputStream.ReadAll (received, 0, received.Length);
1955                                 c.Response.StatusCode = 204;
1956                                 c.Response.Close ();
1957                         });
1958
1959                         Assert.AreEqual (data64KB, received);
1960                 }
1961
1962                 [Test]
1963                 public void BeginWriteAfterAbort ()
1964                 {
1965                         byte [] received = new byte [data64KB.Length];
1966
1967                         this.DoRequest (
1968                         (r, c) =>
1969                         {
1970                                 r.Method = "POST";
1971                                 r.ContentLength = data64KB.Length;
1972
1973                                 Stream s = r.GetRequestStream ();
1974                                 r.Abort();
1975
1976                                 WebException ex = ExceptionAssert.Throws<WebException> (() => s.BeginWrite (data64KB, 0, data64KB.Length, null, null));
1977                                 Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
1978
1979                                 c.Set();
1980                         },
1981                         (c) =>
1982                         {
1983                                 //c.Request.InputStream.ReadAll (received, 0, received.Length);
1984                                 //c.Response.StatusCode = 204;
1985                                 //c.Response.Close();
1986                         });
1987                 }
1988
1989                 [Test]
1990                 public void PrematureStreamCloseAborts ()
1991                 {
1992                         byte [] received = new byte [data64KB.Length];
1993
1994                         this.DoRequest (
1995                         (r, c) =>
1996                         {
1997                                 r.Method = "POST";
1998                                 r.ContentLength = data64KB.Length * 2;
1999
2000                                 Stream s = r.GetRequestStream ();
2001                                 s.Write (data64KB, 0, data64KB.Length);
2002
2003                                 WebException ex = ExceptionAssert.Throws<WebException>(() => s.Close());
2004                                 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
2005
2006                                 c.Set();
2007                         },
2008                         (c) =>
2009                         {
2010                                 c.Request.InputStream.ReadAll (received, 0, received.Length);
2011 //                              c.Response.StatusCode = 204;
2012 //                              c.Response.Close ();
2013                         });
2014                 }
2015
2016                 [Test]
2017                 public void Write ()
2018                 {
2019                         byte [] received = new byte [data64KB.Length];
2020
2021                         this.DoRequest (
2022                         (r, c) =>
2023                         {
2024                                 r.Method = "POST";
2025                                 r.ContentLength = data64KB.Length;
2026
2027                                 using (Stream s = r.GetRequestStream ()) {
2028                                         s.Write (data64KB, 0, data64KB.Length);
2029                                 }
2030
2031                                 r.GetResponse ().Close ();
2032                                 c.Set ();
2033                         },
2034                         (c) =>
2035                         {
2036                                 c.Request.InputStream.ReadAll (received, 0, received.Length);
2037                                 c.Response.StatusCode = 204;
2038                                 c.Response.Close ();
2039                         });
2040
2041                         Assert.AreEqual(data64KB, received);
2042                 }
2043
2044                 /*
2045                 Invalid test: it does not work on linux.
2046                 [pid 30973] send(9, "POST / HTTP/1.1\r\nContent-Length:"..., 89, 0) = 89
2047                 Abort set
2048                 [pid 30970] send(16, "HTTP/1.1 200 OK\r\nServer: Mono-HT"..., 133, 0) = 133
2049                 Calling abort
2050                 [pid 30970] close(16)                   = 0
2051                 Closing!!!
2052                 [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
2053                 Writing...
2054                 [pid 30966] close(4)                    = 0
2055                 OK
2056                  *
2057                  The server sideis closed (FD 16) and the send on the client side (FD 9) succeeds.
2058                 [Test]
2059                 [Category("NotWorking")]
2060                 public void WriteServerAborts ()
2061                 {
2062                         ManualResetEvent abort = new ManualResetEvent (false);
2063                         byte [] received = new byte [data64KB.Length];
2064
2065                         this.DoRequest (
2066                         (r, c) =>
2067                         {
2068                                 r.Method = "POST";
2069                                 r.ContentLength = data64KB.Length;
2070
2071                                 using (Stream s = r.GetRequestStream()) {
2072                                         abort.Set();
2073                                         Thread.Sleep(100);
2074                                         IOException ex = ExceptionAssert.Throws<IOException> (() => s.Write(data64KB, 0, data64KB.Length));
2075                                 }
2076
2077                                 c.Set();
2078                         },
2079                         (c) =>
2080                         {
2081                                 abort.WaitOne();
2082                                 c.Response.Abort();
2083                         });
2084                 }
2085                 **/
2086
2087                 [Test]
2088                 public void Read ()
2089                 {
2090                         byte [] received = new byte [data64KB.Length];
2091
2092                         this.DoRequest (
2093                         (r, c) =>
2094                         {
2095                                 using (HttpWebResponse x = (HttpWebResponse) r.GetResponse ())
2096                                 using (Stream s = x.GetResponseStream()) {
2097                                         s.ReadAll (received, 0, received.Length);
2098                                 }
2099
2100                                 c.Set ();
2101                         },
2102                         (c) =>
2103                         {
2104                                 c.Response.StatusCode = 200;
2105                                 c.Response.ContentLength64 = data64KB.Length;
2106                                 c.Response.OutputStream.Write (data64KB, 0, data64KB.Length);
2107                                 c.Response.OutputStream.Close ();
2108                                 c.Response.Close ();
2109                         });
2110
2111                         Assert.AreEqual (data64KB, received);
2112                 }
2113
2114                 [Test]
2115                 public void ReadTimeout2 ()
2116                 {
2117                         byte [] received = new byte [data64KB.Length];
2118
2119                         this.DoRequest (
2120                         (r, c) =>
2121                         {
2122                                 r.ReadWriteTimeout = 10;
2123                                 using (HttpWebResponse x = (HttpWebResponse) r.GetResponse ())
2124                                 using (Stream s = x.GetResponseStream ()) {
2125                                         WebException ex = ExceptionAssert.Throws<WebException> (() => s.ReadAll (received, 0, received.Length));
2126                                         Assert.AreEqual (ex.Status, WebExceptionStatus.Timeout);
2127                                 }
2128
2129                                 c.Set();
2130                         },
2131                         (c) =>
2132                         {
2133                                 c.Response.StatusCode = 200;
2134                                 c.Response.ContentLength64 = data64KB.Length;
2135                                 c.Response.OutputStream.Write (data64KB, 0, data64KB.Length / 2);
2136                                 Thread.Sleep (1000);
2137 //                              c.Response.OutputStream.Write (data64KB, data64KB.Length / 2, data64KB.Length / 2);
2138                                 c.Response.OutputStream.Close ();
2139                                 c.Response.Close ();
2140                         });
2141                 }
2142
2143                 [Test]
2144                 public void ReadServerAborted ()
2145                 {
2146                         byte [] received = new byte [data64KB.Length];
2147
2148                         this.DoRequest (
2149                         (r, c) =>
2150                         {
2151                                 using (HttpWebResponse x = (HttpWebResponse) r.GetResponse ())
2152                                 using (Stream s = x.GetResponseStream ()) {
2153                                         Assert.AreEqual (1, s.ReadAll (received, 0, received.Length));
2154                                 }
2155
2156                                 c.Set();
2157                         },
2158                         (c) =>
2159                         {
2160                                 c.Response.StatusCode = 200;
2161                                 c.Response.ContentLength64 = data64KB.Length;
2162                                 c.Response.OutputStream.Write (data64KB, 0, 1);
2163                                 c.Response.Abort ();
2164                         });
2165                 }
2166
2167                 [Test]
2168                 public void BeginGetResponse2 ()
2169                 {
2170                         byte [] received = new byte [data64KB.Length];
2171
2172                         this.DoRequest (
2173                         (r, c) =>
2174                         {
2175                                 r.BeginGetResponse ((a) =>
2176                                 {
2177                                         using (HttpWebResponse x = (HttpWebResponse) r.EndGetResponse (a))
2178                                         using (Stream s = x.GetResponseStream ()) {
2179                                                 s.ReadAll (received, 0, received.Length);
2180                                         }
2181
2182                                         c.Set();
2183                                 }, null);
2184                         },
2185                         (c) =>
2186                         {
2187                                 c.Response.StatusCode = 200;
2188                                 c.Response.ContentLength64 = data64KB.Length;
2189                                 c.Response.OutputStream.Write (data64KB, 0, data64KB.Length);
2190                                 c.Response.OutputStream.Close ();
2191                                 c.Response.Close ();
2192                         });
2193
2194                         Assert.AreEqual (data64KB, received);
2195                 }
2196
2197                 [Test]
2198                 public void BeginGetResponseAborts ()
2199                 {
2200                         ManualResetEvent aborted = new ManualResetEvent(false);
2201
2202                         this.DoRequest (
2203                         (r, c) =>
2204                         {
2205                                 r.BeginGetResponse((a) =>
2206                                 {
2207                                         WebException ex = ExceptionAssert.Throws<WebException> (() => r.EndGetResponse (a));
2208                                         Assert.AreEqual (ex.Status, WebExceptionStatus.RequestCanceled);
2209                                         c.Set ();
2210                                 }, null);
2211
2212                                 aborted.WaitOne ();
2213                                 r.Abort ();
2214                         },
2215                         (c) =>
2216                         {
2217                                 aborted.Set ();
2218 //                              Thread.Sleep (100);
2219 //                              c.Response.StatusCode = 200;
2220 //                              c.Response.ContentLength64 = 0;
2221 //                              c.Response.Close ();
2222                         });
2223
2224                         return;
2225                 }
2226                 
2227                 [Test]
2228                 public void TestLargeDataReading ()
2229                 {
2230                         int near2GBStartPosition = rand.Next (int.MaxValue - 500, int.MaxValue);
2231                         AutoResetEvent readyGetLastPortionEvent = new AutoResetEvent (false);
2232                         Exception testException = null;
2233
2234                         DoRequest (
2235                         (request, waitHandle) =>
2236                         {
2237                                 try
2238                                 {
2239                                         const int timeoutMs = 5000;
2240
2241                                         request.Timeout = timeoutMs;
2242                                         request.ReadWriteTimeout = timeoutMs;
2243
2244                                         WebResponse webResponse = request.GetResponse ();
2245                                         Stream webResponseStream = webResponse.GetResponseStream ();
2246                                         Assert.IsNotNull (webResponseStream, null, "#1");
2247                                         
2248                                         Type webConnectionStreamType = webResponseStream.GetType ();
2249                                         FieldInfo totalReadField = webConnectionStreamType.GetField ("totalRead", BindingFlags.NonPublic | BindingFlags.Instance);
2250                                         Assert.IsNotNull (totalReadField, "#2");
2251                                         totalReadField.SetValue (webResponseStream, near2GBStartPosition);
2252                                         
2253                                         byte[] readBuffer = new byte[int.MaxValue - near2GBStartPosition];
2254                                         Assert.AreEqual (webResponseStream.Read (readBuffer, 0, readBuffer.Length), readBuffer.Length, "#3");
2255                                         readyGetLastPortionEvent.Set ();
2256                                         Assert.IsTrue (webResponseStream.Read (readBuffer, 0, readBuffer.Length) > 0);
2257                                         readyGetLastPortionEvent.Set ();
2258                                         
2259                                         webResponse.Close();
2260                                 }
2261                                 catch (Exception e)
2262                                 {
2263                                         testException = e;
2264                                 }
2265                                 finally
2266                                 {
2267                                         waitHandle.Set ();
2268                                 }
2269                         },
2270                         processor =>
2271                         {
2272                                 processor.Request.InputStream.Close ();
2273                                 
2274                                 HttpListenerResponse response = processor.Response;
2275                                 response.SendChunked = true;
2276                                 
2277                                 Stream outputStream = response.OutputStream;
2278                                 var writeBuffer = new byte[int.MaxValue - near2GBStartPosition];
2279                                 outputStream.Write (writeBuffer, 0, writeBuffer.Length);
2280                                 readyGetLastPortionEvent.WaitOne ();
2281                                 outputStream.Write (writeBuffer, 0, writeBuffer.Length);
2282                                 readyGetLastPortionEvent.WaitOne ();
2283                                 
2284                                 response.Close();
2285                         });
2286
2287                         if (testException != null)
2288                                 throw testException;
2289                 }
2290
2291                 void DoRequest (Action<HttpWebRequest, EventWaitHandle> request)
2292                 {
2293                         int port = NetworkHelpers.FindFreePort ();
2294
2295                         ManualResetEvent completed = new ManualResetEvent (false);
2296                         Uri address = new Uri (string.Format ("http://localhost:{0}", port));
2297                         HttpWebRequest client = (HttpWebRequest) WebRequest.Create (address);
2298
2299                         request (client, completed);
2300
2301                         if (!completed.WaitOne (10000))
2302                                 Assert.Fail ("Test hung");
2303                 }
2304
2305                 void DoRequest (Action<HttpWebRequest, EventWaitHandle> request, Action<HttpListenerContext> processor)
2306                 {
2307                         int port = NetworkHelpers.FindFreePort ();
2308
2309                         ManualResetEvent [] completed = new ManualResetEvent [2];
2310                         completed [0] = new ManualResetEvent (false);
2311                         completed [1] = new ManualResetEvent (false);
2312
2313                         using (ListenerScope scope = new ListenerScope (processor, port, completed [0])) {
2314                                 Uri address = new Uri (string.Format ("http://localhost:{0}", port));
2315                                 HttpWebRequest client = (HttpWebRequest) WebRequest.Create (address);
2316
2317                                 ThreadPool.QueueUserWorkItem ((o) => request (client, completed [1]));
2318
2319                                 if (!WaitHandle.WaitAll (completed, 10000))
2320                                         Assert.Fail ("Test hung.");
2321                         }
2322                 }
2323
2324                 [Test]
2325                 [ExpectedException (typeof (ArgumentNullException))]
2326                 public void NullHost ()
2327                 {
2328                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2329                         req.Host = null;
2330                 }
2331
2332                 [Test]
2333                 public void NoHost ()
2334                 {
2335                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2336                         Assert.AreEqual (req.Host, "go-mono.com");
2337                 }
2338
2339                 [Test]
2340                 [ExpectedException (typeof (ArgumentException))]
2341                 public void EmptyHost ()
2342                 {
2343                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2344                         req.Host = "";
2345                 }
2346
2347                 [Test]
2348                 public void HostAndPort ()
2349                 {
2350                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com:80");
2351                         Assert.AreEqual ("go-mono.com", req.Host, "#01");
2352                         req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com:9000");
2353                         Assert.AreEqual ("go-mono.com:9000", req.Host, "#02");
2354                 }
2355
2356                 [Test]
2357                 public void PortRange ()
2358                 {
2359                         for (int i = 0; i < 65536; i++) {
2360                                 if (i == 80)
2361                                         continue;
2362                                 string s = i.ToString ();
2363                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com:" + s);
2364                                 Assert.AreEqual ("go-mono.com:" + s, req.Host, "#" + s);
2365                         }
2366                 }
2367
2368                 [Test]
2369                 [ExpectedException (typeof (ArgumentException))]
2370                 public void PortBelow ()
2371                 {
2372                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2373                         req.Host = "go-mono.com:-1";
2374                 }
2375
2376                 [Test]
2377                 [ExpectedException (typeof (ArgumentException))]
2378                 public void PortAbove ()
2379                 {
2380                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2381                         req.Host = "go-mono.com:65536";
2382                 }
2383
2384                 [Test]
2385                 [ExpectedException (typeof (ArgumentException))]
2386                 public void HostTooLong ()
2387                 {
2388                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2389                         string s = new string ('a', 100);
2390                         req.Host = s + "." + s + "." + s + "." + s + "." + s + "." + s; // Over 255 bytes
2391                 }
2392
2393                 [Test]
2394                 [Category ("NotWorking")] // #5490
2395                 public void InvalidNamesThatWork ()
2396                 {
2397                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2398                         req.Host = "-";
2399                         req.Host = "-.-";
2400                         req.Host = "á";
2401                         req.Host = new string ('a', 64); // Should fail. Max. is 63.
2402                 }
2403
2404                 [Test]
2405                 public void NoDate ()
2406                 {
2407                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2408                         Assert.AreEqual (DateTime.MinValue, req.Date);
2409                 }
2410
2411                 [Test]
2412                 public void UtcDate ()
2413                 {
2414                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://go-mono.com");
2415                         req.Date = DateTime.UtcNow;
2416                         DateTime date = req.Date;
2417                         Assert.AreEqual (DateTimeKind.Local, date.Kind);
2418                 }
2419
2420                 [Test]
2421                 public void AddAndRemoveDate ()
2422                 {
2423                         // Neil Armstrong set his foot on Moon
2424                         var landing = new DateTime (1969, 7, 21, 2, 56, 0, DateTimeKind.Utc);
2425                         Assert.AreEqual (621214377600000000, landing.Ticks);
2426                         var unspecified = new DateTime (1969, 7, 21, 2, 56, 0);
2427                         var local = landing.ToLocalTime ();
2428
2429                         var req = (HttpWebRequest)WebRequest.Create ("http://www.mono-project.com/");
2430                         req.Date = landing;
2431                         Assert.AreEqual (DateTimeKind.Local, req.Date.Kind);
2432                         Assert.AreEqual (local.Ticks, req.Date.Ticks);
2433                         Assert.AreEqual (local, req.Date);
2434
2435                         req.Date = unspecified;
2436                         Assert.AreEqual (DateTimeKind.Local, req.Date.Kind);
2437                         Assert.AreEqual (unspecified.Ticks, req.Date.Ticks);
2438                         Assert.AreEqual (unspecified, req.Date);
2439
2440                         req.Date = local;
2441                         Assert.AreEqual (DateTimeKind.Local, req.Date.Kind);
2442                         Assert.AreEqual (local.Ticks, req.Date.Ticks);
2443                         Assert.AreEqual (local, req.Date);
2444
2445                         req.Date = DateTime.MinValue;
2446                         Assert.AreEqual (DateTimeKind.Unspecified, DateTime.MinValue.Kind);
2447                         Assert.AreEqual (DateTimeKind.Unspecified, req.Date.Kind);
2448                         Assert.AreEqual (0, req.Date.Ticks);
2449
2450                         Assert.AreEqual (null, req.Headers.Get ("Date"));
2451                 }
2452                 
2453                 [Test]
2454                 // Bug #12393
2455                 public void TestIPv6Host ()
2456                 {
2457                         var address = "2001:0000:0000:0001:0001:0001:0157:0000";
2458                         var address2 = '[' + address + ']';
2459                         var uri = new Uri (string.Format ("http://{0}/test.css", address2));
2460                         var hwr = (HttpWebRequest)WebRequest.Create (uri);
2461
2462                         hwr.Host = address2;
2463                         Assert.AreEqual (address2, hwr.Host, "#1");
2464                 }
2465
2466                 [Test]
2467                 // Bug #12393
2468                 [Category ("NotWorking")]
2469                 public void TestIPv6Host2 ()
2470                 {
2471                         var address = "2001:0000:0000:0001:0001:0001:0157:0000";
2472                         var address2 = '[' + address + ']';
2473                         var uri = new Uri (string.Format ("http://{0}/test.css", address2));
2474                         var hwr = (HttpWebRequest)WebRequest.Create (uri);
2475
2476                         try {
2477                                 hwr.Host = address;
2478                                 Assert.Fail ("#1");
2479                         } catch (ArgumentException) {
2480                                 ;
2481                         }
2482                 }
2483
2484 #if NET_4_5
2485                 [Test]
2486                 public void AllowReadStreamBuffering ()
2487                 {
2488                         var hr = WebRequest.CreateHttp ("http://www.google.com");
2489                         Assert.IsFalse (hr.AllowReadStreamBuffering, "#1");
2490                         try {
2491                                 hr.AllowReadStreamBuffering = true;
2492                                 Assert.Fail ("#2");
2493                         } catch (InvalidOperationException) {
2494                         }
2495                 }
2496 #endif
2497
2498                 class ListenerScope : IDisposable {
2499                         EventWaitHandle completed;
2500                         public HttpListener listener;
2501                         Action<HttpListenerContext> processor;
2502
2503                         public ListenerScope (Action<HttpListenerContext> processor, int port, EventWaitHandle completed)
2504                         {
2505                                 this.processor = processor;
2506                                 this.completed = completed;
2507
2508                                 this.listener = new HttpListener ();
2509                                 this.listener.Prefixes.Add (string.Format ("http://localhost:{0}/", port));
2510                                 this.listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
2511                                 this.listener.Start ();
2512
2513                                 this.listener.BeginGetContext (this.RequestHandler, null);
2514                         }
2515
2516                         void RequestHandler (IAsyncResult result)
2517                         {
2518                                 HttpListenerContext context = null;
2519
2520                                 try {
2521                                         context = this.listener.EndGetContext (result);
2522                                 } catch (HttpListenerException ex) {
2523                                         // check if the thread has been aborted as in the case when we are shutting down.
2524                                         if (ex.ErrorCode == 995)
2525                                                 return;
2526                                 } catch (ObjectDisposedException) {
2527                                         return;
2528                                 }
2529
2530                                 ThreadPool.QueueUserWorkItem ((o) =>
2531                                 {
2532                                         try {
2533                                                 this.processor (context);
2534                                         } catch (HttpListenerException) {
2535                                         }
2536                                 });
2537
2538                                 this.completed.Set ();
2539                         }
2540
2541                         public void Dispose ()
2542                         {
2543                                 this.listener.Stop ();
2544                         }
2545                 }
2546
2547 #if !MOBILE
2548                 class SslHttpServer : HttpServer {
2549                         X509Certificate _certificate;
2550
2551                         protected override void Run ()
2552                         {
2553                                 try {
2554                                         Socket client = sock.Accept ();
2555                                         NetworkStream ns = new NetworkStream (client, true);
2556                                         SslServerStream s = new SslServerStream (ns, Certificate, false, false);
2557                                         s.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback (GetPrivateKey);
2558
2559                                         StreamReader reader = new StreamReader (s);
2560                                         StreamWriter writer = new StreamWriter (s, Encoding.ASCII);
2561
2562                                         string line;
2563                                         string hello = "<html><body><h1>Hello World!</h1></body></html>";
2564                                         string answer = "HTTP/1.0 200\r\n" +
2565                                                         "Connection: close\r\n" +
2566                                                         "Content-Type: text/html\r\n" +
2567                                                         "Content-Encoding: " + Encoding.ASCII.WebName + "\r\n" +
2568                                                         "Content-Length: " + hello.Length + "\r\n" +
2569                                                         "\r\n" + hello;
2570
2571                                         // Read the headers
2572                                         do {
2573                                                 line = reader.ReadLine ();
2574                                         } while (line != "" && line != null && line.Length > 0);
2575
2576                                         // Now the content. We know it's 100 bytes.
2577                                         // This makes BeginRead in sslclientstream block.
2578                                         char [] cs = new char [100];
2579                                         reader.Read (cs, 0, 100);
2580
2581                                         writer.Write (answer);
2582                                         writer.Flush ();
2583                                         if (evt.WaitOne (5000, false))
2584                                                 error = new Exception ("Timeout when stopping the server");
2585                                 } catch (Exception e) {
2586                                         error = e;
2587                                 }
2588                         }
2589
2590                         X509Certificate Certificate {
2591                                 get {
2592                                         if (_certificate == null)
2593                                                 _certificate = new X509Certificate (CertData.Certificate);
2594
2595                                         return _certificate;
2596                                 }
2597                         }
2598
2599                         AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
2600                         {
2601                                 PrivateKey key = new PrivateKey (CertData.PrivateKey, null);
2602                                 return key.RSA;
2603                         }
2604                 }
2605
2606                 class CertData {
2607                         public readonly static byte [] Certificate = {
2608                                 48, 130, 1, 191, 48, 130, 1, 40, 160, 3, 2, 1, 2, 2, 16, 36, 
2609                                 14, 97, 190, 146, 132, 208, 71, 175, 6, 87, 168, 185, 175, 55, 43, 48, 
2610                                 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 18, 
2611                                 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 111, 110, 122, 97, 
2612                                 108, 111, 48, 30, 23, 13, 48, 53, 48, 54, 50, 50, 49, 57, 51, 48, 
2613                                 52, 54, 90, 23, 13, 51, 57, 49, 50, 51, 49, 50, 51, 53, 57, 53, 
2614                                 57, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 
2615                                 111, 110, 122, 97, 108, 111, 48, 129, 158, 48, 13, 6, 9, 42, 134, 72, 
2616                                 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 140, 0, 48, 129, 136, 2, 
2617                                 129, 129, 0, 138, 9, 38, 25, 166, 252, 59, 26, 39, 184, 128, 216, 38, 
2618                                 73, 41, 86, 30, 228, 160, 205, 41, 135, 115, 223, 44, 62, 42, 198, 178, 
2619                                 190, 81, 11, 25, 21, 216, 49, 179, 130, 246, 52, 97, 175, 212, 94, 157, 
2620                                 231, 162, 66, 161, 103, 63, 204, 83, 141, 172, 119, 97, 225, 206, 98, 101, 
2621                                 210, 106, 2, 206, 81, 90, 173, 47, 41, 199, 209, 241, 177, 177, 96, 207, 
2622                                 254, 220, 190, 66, 180, 153, 0, 209, 14, 178, 69, 194, 3, 37, 116, 239, 
2623                                 49, 23, 185, 245, 255, 126, 35, 85, 246, 56, 244, 107, 117, 24, 14, 57, 
2624                                 9, 111, 147, 189, 220, 142, 57, 104, 153, 193, 205, 19, 14, 22, 157, 16, 
2625                                 24, 80, 201, 2, 2, 0, 17, 163, 23, 48, 21, 48, 19, 6, 3, 85, 
2626                                 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 
2627                                 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3, 
2628                                 129, 129, 0, 64, 49, 57, 253, 218, 198, 229, 51, 189, 12, 154, 225, 183, 
2629                                 160, 147, 90, 113, 172, 69, 122, 28, 77, 97, 215, 231, 194, 150, 29, 196, 
2630                                 65, 95, 218, 99, 142, 111, 79, 205, 109, 76, 32, 92, 220, 76, 88, 53, 
2631                                 237, 80, 11, 85, 44, 91, 21, 210, 12, 34, 223, 234, 18, 187, 136, 62, 
2632                                 26, 240, 103, 180, 12, 226, 221, 250, 247, 129, 51, 23, 129, 165, 56, 67, 
2633                                 43, 83, 244, 110, 207, 24, 253, 195, 16, 46, 80, 113, 80, 18, 2, 254, 
2634                                 120, 147, 151, 164, 23, 210, 230, 100, 19, 197, 179, 28, 194, 48, 106, 159, 
2635                                 155, 144, 37, 82, 44, 160, 40, 52, 146, 174, 77, 188, 160, 230, 75, 172, 
2636                                 123, 3, 254, 
2637                         };
2638
2639                         public readonly static byte [] PrivateKey = {
2640                                 30, 241, 181, 176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 
2641                                 0, 0, 0, 0, 84, 2, 0, 0, 7, 2, 0, 0, 0, 36, 0, 0, 
2642                                 82, 83, 65, 50, 0, 4, 0, 0, 17, 0, 0, 0, 201, 80, 24, 16, 
2643                                 157, 22, 14, 19, 205, 193, 153, 104, 57, 142, 220, 189, 147, 111, 9, 57, 
2644                                 14, 24, 117, 107, 244, 56, 246, 85, 35, 126, 255, 245, 185, 23, 49, 239, 
2645                                 116, 37, 3, 194, 69, 178, 14, 209, 0, 153, 180, 66, 190, 220, 254, 207, 
2646                                 96, 177, 177, 241, 209, 199, 41, 47, 173, 90, 81, 206, 2, 106, 210, 101, 
2647                                 98, 206, 225, 97, 119, 172, 141, 83, 204, 63, 103, 161, 66, 162, 231, 157, 
2648                                 94, 212, 175, 97, 52, 246, 130, 179, 49, 216, 21, 25, 11, 81, 190, 178, 
2649                                 198, 42, 62, 44, 223, 115, 135, 41, 205, 160, 228, 30, 86, 41, 73, 38, 
2650                                 216, 128, 184, 39, 26, 59, 252, 166, 25, 38, 9, 138, 175, 88, 190, 223, 
2651                                 27, 24, 224, 123, 190, 69, 164, 234, 129, 59, 108, 229, 248, 62, 187, 15, 
2652                                 235, 147, 162, 83, 47, 123, 170, 190, 224, 31, 215, 110, 143, 31, 227, 216, 
2653                                 85, 88, 154, 83, 207, 229, 41, 28, 237, 116, 181, 17, 37, 141, 224, 185, 
2654                                 164, 144, 141, 233, 164, 138, 177, 241, 115, 181, 230, 150, 7, 92, 139, 141, 
2655                                 113, 95, 57, 191, 211, 165, 217, 250, 197, 68, 164, 184, 168, 43, 48, 65, 
2656                                 177, 237, 173, 144, 148, 221, 62, 189, 147, 63, 216, 188, 206, 103, 226, 171, 
2657                                 32, 20, 230, 116, 144, 192, 1, 39, 202, 87, 74, 250, 6, 142, 188, 23, 
2658                                 45, 4, 112, 191, 253, 67, 69, 70, 128, 143, 44, 234, 41, 96, 195, 82, 
2659                                 202, 35, 158, 149, 240, 151, 23, 25, 166, 179, 85, 144, 58, 120, 149, 229, 
2660                                 205, 34, 8, 110, 86, 119, 130, 210, 37, 173, 65, 71, 169, 67, 8, 51, 
2661                                 20, 96, 51, 155, 3, 39, 85, 187, 40, 193, 57, 19, 99, 78, 173, 28, 
2662                                 129, 154, 108, 175, 8, 138, 237, 71, 27, 148, 129, 35, 47, 57, 101, 237, 
2663                                 168, 178, 227, 221, 212, 63, 124, 254, 253, 215, 183, 159, 49, 103, 74, 49, 
2664                                 67, 160, 171, 72, 194, 215, 108, 251, 178, 18, 184, 100, 211, 105, 21, 186, 
2665                                 39, 66, 218, 154, 72, 222, 90, 237, 179, 251, 51, 224, 212, 56, 251, 6, 
2666                                 209, 151, 198, 176, 89, 110, 35, 141, 248, 237, 223, 68, 135, 206, 207, 169, 
2667                                 254, 219, 243, 130, 71, 11, 94, 113, 233, 92, 63, 156, 169, 72, 215, 110, 
2668                                 95, 94, 191, 50, 59, 89, 187, 59, 183, 99, 161, 146, 233, 245, 219, 80, 
2669                                 87, 113, 251, 50, 144, 195, 158, 46, 189, 232, 119, 91, 75, 22, 6, 176, 
2670                                 39, 206, 25, 196, 213, 195, 219, 24, 28, 103, 104, 36, 137, 128, 4, 119, 
2671                                 163, 40, 126, 87, 18, 86, 128, 243, 213, 101, 2, 237, 78, 64, 160, 55, 
2672                                 199, 93, 90, 126, 175, 199, 55, 89, 234, 190, 5, 16, 196, 88, 28, 208, 
2673                                 28, 92, 32, 115, 204, 9, 202, 101, 15, 123, 43, 75, 90, 144, 95, 179, 
2674                                 102, 249, 57, 150, 204, 99, 147, 203, 16, 63, 81, 244, 226, 237, 82, 204, 
2675                                 20, 200, 140, 65, 83, 217, 161, 23, 123, 37, 115, 12, 100, 73, 70, 190, 
2676                                 32, 235, 174, 140, 148, 157, 47, 238, 40, 208, 228, 80, 54, 187, 156, 252, 
2677                                 253, 230, 231, 156, 138, 125, 96, 79, 3, 27, 143, 55, 146, 169, 165, 61, 
2678                                 238, 60, 227, 77, 217, 93, 117, 122, 111, 46, 173, 113, 
2679                         };
2680                 }
2681 #endif
2682
2683                 [Test]
2684                 public void CookieContainerTest ()
2685                 {
2686                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2687                         string url = "http://" + ep.ToString ();
2688
2689                         using (SocketResponder responder = new SocketResponder (ep, s => CookieRequestHandler (s))) {
2690                                 CookieContainer container = new CookieContainer ();
2691                                 container.Add(new Uri (url), new Cookie ("foo", "bar"));
2692                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
2693                                 request.CookieContainer = container;
2694                                 WebHeaderCollection headers = request.Headers;
2695                                 headers.Add("Cookie", "foo=baz");
2696                                 HttpWebResponse response = (HttpWebResponse) request.GetResponse ();
2697                                 string responseString = null;
2698                                 using (StreamReader reader = new StreamReader (response.GetResponseStream ())) {
2699                                         responseString = reader.ReadToEnd ();
2700                                 }
2701                                 response.Close ();
2702                                 Assert.AreEqual (1, response.Cookies.Count, "#01");
2703                                 Assert.AreEqual ("foo=bar", response.Headers.Get("Set-Cookie"), "#02");
2704                         }
2705
2706                         using (SocketResponder responder = new SocketResponder (ep, s => CookieRequestHandler (s))) {
2707                                 CookieContainer container = new CookieContainer ();
2708                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
2709                                 request.CookieContainer = container;
2710                                 WebHeaderCollection headers = request.Headers;
2711                                 headers.Add("Cookie", "foo=baz");
2712                                 HttpWebResponse response = (HttpWebResponse) request.GetResponse ();
2713                                 string responseString = null;
2714                                 using (StreamReader reader = new StreamReader (response.GetResponseStream ())) {
2715                                         responseString = reader.ReadToEnd ();
2716                                 }
2717                                 response.Close ();
2718                                 Assert.AreEqual (0, response.Cookies.Count, "#03");
2719                                 Assert.AreEqual ("", response.Headers.Get("Set-Cookie"), "#04");
2720                         }
2721                 }
2722
2723                 internal static byte[] CookieRequestHandler (Socket socket)
2724                 {
2725                         MemoryStream ms = new MemoryStream ();
2726                         byte[] buffer = new byte[4096];
2727                         int bytesReceived = socket.Receive (buffer);
2728                         while (bytesReceived > 0) {
2729                                 ms.Write(buffer, 0, bytesReceived);
2730                                 // We don't check for Content-Length or anything else here, so we give the client a little time to write
2731                                 // after sending the headers
2732                                 Thread.Sleep(200);
2733                                 if (socket.Available > 0) {
2734                                         bytesReceived = socket.Receive (buffer);
2735                                 } else {
2736                                         bytesReceived = 0;
2737                                 }
2738                         }
2739                         ms.Flush();
2740                         ms.Position = 0;
2741                         string cookies = string.Empty;
2742                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
2743                                 string line;
2744                                 while ((line = sr.ReadLine ()) != null) {
2745                                         if (line.StartsWith ("Cookie:")) {
2746                                                 cookies = line.Substring ("cookie: ".Length);
2747                                         }
2748                                 }
2749                         }
2750
2751                         StringWriter sw = new StringWriter ();
2752                         sw.WriteLine ("HTTP/1.1 200 OK");
2753                         sw.WriteLine ("Content-Type: text/xml");
2754                         sw.WriteLine ("Set-Cookie: " + cookies);
2755                         sw.WriteLine ("Content-Length: " + cookies.Length.ToString (CultureInfo.InvariantCulture));
2756                         sw.WriteLine ();
2757                         sw.Write (cookies);
2758                         sw.Flush ();
2759
2760                         return Encoding.UTF8.GetBytes (sw.ToString ());
2761                 }
2762         }
2763
2764         [TestFixture]
2765         public class HttpRequestStreamTest
2766         {
2767                 [Test]
2768                 public void BeginRead ()
2769                 {
2770                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2771                         string url = "http://" + ep.ToString () + "/test/";
2772
2773                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2774                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2775                                 req.Method = "POST";
2776
2777                                 using (Stream rs = req.GetRequestStream ()) {
2778                                         byte [] buffer = new byte [10];
2779                                         try {
2780                                                 rs.BeginRead (buffer, 0, buffer.Length, null, null);
2781                                                 Assert.Fail ("#1");
2782                                         } catch (NotSupportedException ex) {
2783                                                 // The stream does not support reading
2784                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
2785                                                 Assert.IsNull (ex.InnerException, "#3");
2786                                                 Assert.IsNotNull (ex.Message, "#4");
2787                                         } finally {
2788                                                 req.Abort ();
2789                                         }
2790                                 }
2791                         }
2792                 }
2793
2794                 [Test]
2795                 [Category("MobileNotWorking")]
2796                 public void BeginWrite_Request_Aborted ()
2797                 {
2798                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2799                         string url = "http://" + ep.ToString () + "/test/";
2800
2801                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2802                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2803                                 req.Method = "POST";
2804
2805                                 using (Stream rs = req.GetRequestStream ()) {
2806                                         req.Abort ();
2807                                         try {
2808                                                 rs.BeginWrite (new byte [] { 0x2a, 0x2f }, 0, 2, null, null);
2809                                                 Assert.Fail ("#1");
2810                                         } catch (WebException ex) {
2811                                                 // The request was aborted: The request was canceled
2812                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
2813                                                 Assert.IsNull (ex.InnerException, "#3");
2814                                                 Assert.IsNotNull (ex.Message, "#4");
2815                                                 Assert.IsNull (ex.Response, "#5");
2816                                                 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
2817                                         }
2818                                 }
2819                         }
2820                 }
2821
2822                 [Test]
2823                 public void CanRead ()
2824                 {
2825                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2826                         string url = "http://" + ep.ToString () + "/test/";
2827
2828                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2829                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2830                                 req.Method = "POST";
2831
2832                                 Stream rs = req.GetRequestStream ();
2833                                 try {
2834                                         Assert.IsFalse (rs.CanRead, "#1");
2835                                         rs.Close ();
2836                                         Assert.IsFalse (rs.CanRead, "#2");
2837                                 } finally {
2838                                         rs.Close ();
2839                                         req.Abort ();
2840                                 }
2841                         }
2842                 }
2843
2844                 [Test]
2845                 public void CanSeek ()
2846                 {
2847                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2848                         string url = "http://" + ep.ToString () + "/test/";
2849
2850                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2851                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2852                                 req.Method = "POST";
2853
2854                                 Stream rs = req.GetRequestStream ();
2855                                 try {
2856                                         Assert.IsFalse (rs.CanSeek, "#1");
2857                                         rs.Close ();
2858                                         Assert.IsFalse (rs.CanSeek, "#2");
2859                                 } finally {
2860                                         rs.Close ();
2861                                         req.Abort ();
2862                                 }
2863                         }
2864                 }
2865
2866                 [Test] // bug #324182
2867                 public void CanTimeout ()
2868                 {
2869                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2870                         string url = "http://" + ep.ToString () + "/test/";
2871
2872                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2873                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2874                                 req.Method = "POST";
2875
2876                                 Stream rs = req.GetRequestStream ();
2877                                 try {
2878                                         Assert.IsTrue (rs.CanTimeout, "#1");
2879                                         rs.Close ();
2880                                         Assert.IsTrue (rs.CanTimeout, "#2");
2881                                 } finally {
2882                                         rs.Close ();
2883                                         req.Abort ();
2884                                 }
2885                         }
2886                 }
2887
2888                 [Test]
2889                 public void CanWrite ()
2890                 {
2891                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2892                         string url = "http://" + ep.ToString () + "/test/";
2893
2894                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2895                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2896                                 req.Method = "POST";
2897
2898                                 Stream rs = req.GetRequestStream ();
2899                                 try {
2900                                         Assert.IsTrue (rs.CanWrite, "#1");
2901                                         rs.Close ();
2902                                         Assert.IsFalse (rs.CanWrite, "#2");
2903                                 } finally {
2904                                         rs.Close ();
2905                                         req.Abort ();
2906                                 }
2907                         }
2908                 }
2909
2910                 [Test]
2911                 public void Read ()
2912                 {
2913                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2914                         string url = "http://" + ep.ToString () + "/test/";
2915
2916                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2917                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2918                                 req.Method = "POST";
2919
2920                                 using (Stream rs = req.GetRequestStream ()) {
2921                                         byte [] buffer = new byte [10];
2922                                         try {
2923                                                 rs.Read (buffer, 0, buffer.Length);
2924                                                 Assert.Fail ("#1");
2925                                         } catch (NotSupportedException ex) {
2926                                                 // The stream does not support reading
2927                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
2928                                                 Assert.IsNull (ex.InnerException, "#3");
2929                                                 Assert.IsNotNull (ex.Message, "#4");
2930                                         } finally {
2931                                                 req.Abort ();
2932                                         }
2933                                 }
2934                         }
2935                 }
2936
2937                 [Test]
2938                 public void ReadByte ()
2939                 {
2940                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2941                         string url = "http://" + ep.ToString () + "/test/";
2942
2943                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2944                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2945                                 req.Method = "POST";
2946
2947                                 using (Stream rs = req.GetRequestStream ()) {
2948                                         try {
2949                                                 rs.ReadByte ();
2950                                                 Assert.Fail ("#1");
2951                                         } catch (NotSupportedException ex) {
2952                                                 // The stream does not support reading
2953                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
2954                                                 Assert.IsNull (ex.InnerException, "#3");
2955                                                 Assert.IsNotNull (ex.Message, "#4");
2956                                         } finally {
2957                                                 req.Abort ();
2958                                         }
2959                                 }
2960                         }
2961                 }
2962
2963                 [Test]
2964                 public void ReadTimeout ()
2965                 {
2966                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2967                         string url = "http://" + ep.ToString () + "/test/";
2968
2969                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2970                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2971                                 req.Method = "POST";
2972
2973                                 Stream rs = req.GetRequestStream ();
2974                                 try {
2975                                         Assert.AreEqual (300000, rs.ReadTimeout, "#1");
2976                                         rs.Close ();
2977                                         Assert.AreEqual (300000, rs.ReadTimeout, "#2");
2978                                 } finally {
2979                                         rs.Close ();
2980                                         req.Abort ();
2981                                 }
2982                         }
2983                 }
2984
2985                 [Test]
2986                 public void Seek ()
2987                 {
2988                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
2989                         string url = "http://" + ep.ToString () + "/test/";
2990
2991                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
2992                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
2993                                 req.Method = "POST";
2994
2995                                 using (Stream rs = req.GetRequestStream ()) {
2996                                         try {
2997                                                 rs.Seek (0, SeekOrigin.Current);
2998                                                 Assert.Fail ("#1");
2999                                         } catch (NotSupportedException ex) {
3000                                                 // This stream does not support seek operations
3001                                                 Assert.AreEqual (typeof (NotSupportedException), ex.GetType (), "#2");
3002                                                 Assert.IsNull (ex.InnerException, "#3");
3003                                                 Assert.IsNotNull (ex.Message, "#4");
3004                                         } finally {
3005                                                 req.Abort ();
3006                                         }
3007                                 }
3008                         }
3009                 }
3010
3011                 [Test]
3012                 public void Write_Buffer_Null ()
3013                 {
3014                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3015                         string url = "http://" + ep.ToString () + "/test/";
3016
3017                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3018                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3019                                 req.Method = "POST";
3020
3021                                 using (Stream rs = req.GetRequestStream ()) {
3022                                         try {
3023                                                 rs.Write ((byte []) null, -1, -1);
3024                                                 Assert.Fail ("#1");
3025                                         } catch (ArgumentNullException ex) {
3026                                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
3027                                                 Assert.IsNull (ex.InnerException, "#3");
3028                                                 Assert.IsNotNull (ex.Message, "#4");
3029                                                 Assert.AreEqual ("buffer", ex.ParamName, "#5");
3030                                         }
3031                                 }
3032
3033                                 req.Abort ();
3034                         }
3035                 }
3036
3037                 [Test]
3038                 public void Write_Count_Negative ()
3039                 {
3040                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3041                         string url = "http://" + ep.ToString () + "/test/";
3042
3043                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3044                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3045                                 req.Method = "POST";
3046
3047                                 using (Stream rs = req.GetRequestStream ()) {
3048                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3049                                         try {
3050                                                 rs.Write (buffer, 1, -1);
3051                                                 Assert.Fail ("#1");
3052                                         } catch (ArgumentOutOfRangeException ex) {
3053                                                 // Specified argument was out of the range of valid values
3054                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
3055                                                 Assert.IsNull (ex.InnerException, "#A3");
3056                                                 Assert.IsNotNull (ex.Message, "#A4");
3057                                                 Assert.AreEqual ("size", ex.ParamName, "#A5");
3058                                         }
3059                                 }
3060
3061                                 req.Abort ();
3062                         }
3063                 }
3064
3065                 [Test]
3066                 public void Write_Count_Overflow ()
3067                 {
3068                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3069                         string url = "http://" + ep.ToString () + "/test/";
3070
3071                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3072                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3073                                 req.Method = "POST";
3074
3075                                 using (Stream rs = req.GetRequestStream ()) {
3076                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3077                                         try {
3078                                                 rs.Write (buffer, buffer.Length - 2, 3);
3079                                                 Assert.Fail ("#1");
3080                                         } catch (ArgumentOutOfRangeException ex) {
3081                                                 // Specified argument was out of the range of valid values
3082                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
3083                                                 Assert.IsNull (ex.InnerException, "#3");
3084                                                 Assert.IsNotNull (ex.Message, "#4");
3085                                                 Assert.AreEqual ("size", ex.ParamName, "#5");
3086                                         }
3087                                 }
3088
3089                                 req.Abort ();
3090                         }
3091                 }
3092
3093                 [Test]
3094                 public void Write_Offset_Negative ()
3095                 {
3096                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3097                         string url = "http://" + ep.ToString () + "/test/";
3098
3099                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3100                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3101                                 req.Method = "POST";
3102
3103                                 using (Stream rs = req.GetRequestStream ()) {
3104                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3105                                         try {
3106                                                 rs.Write (buffer, -1, 0);
3107                                                 Assert.Fail ("#1");
3108                                         } catch (ArgumentOutOfRangeException ex) {
3109                                                 // Specified argument was out of the range of valid values
3110                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
3111                                                 Assert.IsNull (ex.InnerException, "#3");
3112                                                 Assert.IsNotNull (ex.Message, "#4");
3113                                                 Assert.AreEqual ("offset", ex.ParamName, "#5");
3114                                         }
3115                                 }
3116
3117                                 req.Abort ();
3118                         }
3119                 }
3120
3121                 [Test]
3122                 public void Write_Offset_Overflow ()
3123                 {
3124                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3125                         string url = "http://" + ep.ToString () + "/test/";
3126
3127                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3128                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3129                                 req.Method = "POST";
3130
3131                                 using (Stream rs = req.GetRequestStream ()) {
3132                                         byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d, 0x00, 0x0f };
3133                                         try {
3134                                                 rs.Write (buffer, buffer.Length + 1, 0);
3135                                                 Assert.Fail ("#1");
3136                                         } catch (ArgumentOutOfRangeException ex) {
3137                                                 // Specified argument was out of the range of valid values
3138                                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#2");
3139                                                 Assert.IsNull (ex.InnerException, "#3");
3140                                                 Assert.IsNotNull (ex.Message, "#4");
3141                                                 Assert.AreEqual ("offset", ex.ParamName, "#5");
3142                                         }
3143                                 }
3144
3145                                 req.Abort ();
3146                         }
3147                 }
3148
3149                 [Test]
3150                 public void Write_Request_Aborted ()
3151                 {
3152                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3153                         string url = "http://" + ep.ToString () + "/test/";
3154
3155                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3156                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3157                                 req.Method = "POST";
3158
3159                                 using (Stream rs = req.GetRequestStream ()) {
3160                                         req.Abort ();
3161                                         try {
3162                                                 rs.Write (new byte [0], 0, 0);
3163                                                 Assert.Fail ("#1");
3164                                         } catch (WebException ex) {
3165                                                 // The request was aborted: The request was canceled
3166                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
3167                                                 Assert.IsNull (ex.InnerException, "#3");
3168                                                 Assert.IsNotNull (ex.Message, "#4");
3169                                                 Assert.IsNull (ex.Response, "#5");
3170                                                 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
3171                                         }
3172                                 }
3173                         }
3174                 }
3175
3176                 [Test]
3177                 [Category ("NotWorking")]
3178                 public void Write_Stream_Closed ()
3179                 {
3180                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3181                         string url = "http://" + ep.ToString () + "/test/";
3182
3183                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3184                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3185                                 req.Method = "POST";
3186
3187                                 using (Stream rs = req.GetRequestStream ()) {
3188                                         rs.Close ();
3189                                         try {
3190                                                 rs.Write (new byte [0], 0, 0);
3191                                                 Assert.Fail ("#1");
3192                                         } catch (WebException ex) {
3193                                                 // The request was aborted: The connection was closed unexpectedly
3194                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
3195                                                 Assert.IsNull (ex.InnerException, "#3");
3196                                                 Assert.IsNotNull (ex.Message, "#4");
3197                                                 Assert.IsNull (ex.Response, "#5");
3198                                                 Assert.AreEqual (WebExceptionStatus.ConnectionClosed, ex.Status, "#6");
3199                                         }
3200                                 }
3201                         }
3202                 }
3203
3204                 [Test]
3205                 public void WriteByte_Request_Aborted ()
3206                 {
3207                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3208                         string url = "http://" + ep.ToString () + "/test/";
3209
3210                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3211                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3212                                 req.Method = "POST";
3213
3214                                 using (Stream rs = req.GetRequestStream ()) {
3215                                         req.Abort ();
3216                                         try {
3217                                                 rs.WriteByte (0x2a);
3218                                                 Assert.Fail ("#1");
3219                                         } catch (WebException ex) {
3220                                                 // The request was aborted: The request was canceled
3221                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
3222                                                 Assert.IsNull (ex.InnerException, "#3");
3223                                                 Assert.IsNotNull (ex.Message, "#4");
3224                                                 Assert.IsNull (ex.Response, "#5");
3225                                                 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#6");
3226                                         }
3227                                 }
3228                         }
3229                 }
3230
3231                 [Test]
3232                 public void WriteTimeout ()
3233                 {
3234                         IPEndPoint ep = NetworkHelpers.LocalEphemeralEndPoint ();
3235                         string url = "http://" + ep.ToString () + "/test/";
3236
3237                         using (SocketResponder responder = new SocketResponder (ep, s => HttpWebRequestTest.EchoRequestHandler (s))) {
3238                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
3239                                 req.Method = "POST";
3240
3241                                 Stream rs = req.GetRequestStream ();
3242                                 try {
3243                                         Assert.AreEqual (300000, rs.WriteTimeout, "#1");
3244                                         rs.Close ();
3245                                         Assert.AreEqual (300000, rs.WriteTimeout, "#2");
3246                                 } finally {
3247                                         rs.Close ();
3248                                         req.Abort ();
3249                                 }
3250                         }
3251                 }
3252
3253                 [Test]
3254                 // Bug6737
3255                 // This test is supposed to fail prior to .NET 4.0
3256                 public void Post_EmptyRequestStream ()
3257                 {
3258                         var wr = HttpWebRequest.Create ("http://google.com");
3259                         wr.Method = "POST";
3260                         wr.GetRequestStream ();
3261                         
3262                         var gr = wr.BeginGetResponse (delegate { }, null);
3263                         Assert.AreEqual (true, gr.AsyncWaitHandle.WaitOne (5000), "#1");
3264                 }
3265         }
3266
3267         static class StreamExtensions {
3268                 public static int ReadAll(this Stream stream, byte[] buffer, int offset, int count)
3269                 {
3270                         int totalRead = 0;
3271
3272                         while (totalRead < count) {
3273                                 int bytesRead = stream.Read (buffer, offset + totalRead, count - totalRead);
3274                                 if (bytesRead == 0)
3275                                         break;
3276
3277                                 totalRead += bytesRead;
3278                         }
3279
3280                         return totalRead;
3281                 }
3282         }
3283
3284         static class ExceptionAssert {
3285                 /// <summary>
3286                 /// Asserts that the function throws an exception.
3287                 /// </summary>
3288                 /// <param name="f">A function execute that is expected to raise an exception.</param>
3289                 /// <typeparam name="T">The type of exception that is expected.</typeparam>
3290                 /// <returns>The exception thrown.</returns>
3291                 /// <exception cref="AssertFailedException">If the function does not throw an exception 
3292                 /// or throws a different exception.</exception>
3293                 /// <example><![CDATA[
3294                 ///     ExceptionAssert.Throws(typeof(ArgumentNullException), delegate {
3295                 ///         myObject.myFunction(null); });
3296                 /// ]]></example>
3297                 public static T Throws<T> (Action f) where T : Exception {
3298                         Exception actualException = null;
3299
3300                         try {
3301                                 f ();
3302                         } catch (Exception ex) {
3303                                 actualException = ex;
3304                         }
3305
3306                         if (actualException == null)
3307                                 throw new AssertionException (string.Format (
3308                                         "No exception thrown. Expected '{0}'",
3309                                         typeof (T).FullName));
3310                         else if (typeof(T) != actualException.GetType())
3311                                 throw new AssertionException (string.Format (
3312                                         "Caught exception of type '{0}'. Expected '{1}':{2}",
3313                                         actualException.GetType().FullName,
3314                                         typeof (T).FullName,
3315                                         Environment.NewLine + actualException));
3316
3317                         return (T) actualException;
3318                 }
3319         }
3320 }