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