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