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