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