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