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