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