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