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