* HttpWebRequestTest.cs: Added tests for bugs #465613, #510661,
[mono.git] / mcs / class / System / Test / System.Net / HttpWebRequestTest.cs
1 //
2 // HttpWebRequestTest.cs - NUnit Test Cases for System.Net.HttpWebRequest
3 //
4 // Authors:
5 //   Lawrence Pit (loz@cable.a2000.nl)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
9 // (C) 2003 Martin Willemoes Hansen
10 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com
11 //
12
13 using NUnit.Framework;
14 using System;
15 using System.Collections;
16 using System.Collections.Specialized;
17 using System.Globalization;
18 using System.IO;
19 using System.Net;
20 using System.Net.Sockets;
21 using System.Security.Cryptography;
22 using System.Security.Cryptography.X509Certificates;
23 using System.Text;
24 using System.Threading;
25 #if !TARGET_JVM
26 using Mono.Security.Authenticode;
27 using Mono.Security.Protocol.Tls;
28 #endif
29
30 namespace MonoTests.System.Net
31 {
32         [TestFixture]
33         public class HttpWebRequestTest
34         {
35                 [Test]
36 #if TARGET_JVM
37                 [Ignore ("Ignore failures in Sys.Net")]
38 #endif
39                 public void Proxy_Null ()
40                 {
41                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
42                         Assert.IsNotNull (req.Proxy, "#1");
43 #if NET_2_0
44                         req.Proxy = null;
45                         Assert.IsNull (req.Proxy, "#2");
46 #else
47                         try {
48                                 req.Proxy = null;
49                                 Assert.Fail ("#2");
50                         } catch (ArgumentNullException ex) {
51                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#3");
52                                 Assert.IsNull (ex.InnerException, "#4");
53                                 Assert.IsNotNull (ex.Message, "#5");
54                                 Assert.IsNotNull (ex.ParamName, "#6");
55                                 Assert.AreEqual ("value", ex.ParamName, "#7");
56                         }
57 #endif
58                 }
59
60                 [Test]
61                 [Category("InetAccess")]
62 #if TARGET_JVM
63                 [Ignore ("NMA - wrong cookies number returned")]
64 #endif
65                 public void Sync ()
66                 {
67                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
68                         Assertion.AssertNotNull ("req:If Modified Since: ", req.IfModifiedSince);
69
70                         req.UserAgent = "MonoClient v1.0";
71                         Assert.AreEqual ("User-Agent", req.Headers.GetKey (0), "#A1");
72                         Assert.AreEqual ("MonoClient v1.0", req.Headers.Get (0), "#A2");
73
74                         HttpWebResponse res = (HttpWebResponse) req.GetResponse ();
75                         Assert.AreEqual ("OK", res.StatusCode.ToString (), "#B1");
76                         Assert.AreEqual ("OK", res.StatusDescription, "#B2");
77
78                         Assert.AreEqual ("text/html; charset=ISO-8859-1", res.Headers.Get ("Content-Type"), "#C1");
79                         Assert.IsNotNull (res.LastModified, "#C2");
80                         Assert.AreEqual (0, res.Cookies.Count, "#C3");
81
82                         res.Close ();
83                 }
84
85                 [Test]
86                 public void AddRange ()
87                 {
88                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
89                         req.AddRange (10);
90                         req.AddRange (50, 90);
91                         req.AddRange ("bytes", 100); 
92                         req.AddRange ("bytes", 100, 120);
93                         Assertion.AssertEquals ("#1", "bytes=10-,50-90,100-,100-120", req.Headers ["Range"]);
94                         try {
95                                 req.AddRange ("bits", 2000);
96                                 Assertion.Fail ("#2");
97                         } catch (InvalidOperationException) {}
98                 }
99
100                 [Test] // bug #471782
101                 public void CloseRequestStreamAfterReadingResponse ()
102                 {
103                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
104                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
105
106                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
107                                 responder.Start ();
108
109                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
110                                 req.Method = "POST";
111                                 req.Timeout = 2000;
112                                 req.ReadWriteTimeout = 2000;
113
114                                 byte [] data = new byte [128];
115                                 req.ContentLength = data.Length;
116
117                                 Stream rs = req.GetRequestStream ();
118                                 rs.Write (data, 0, data.Length);
119                                 rs.Flush ();
120
121                                 HttpWebResponse response = (HttpWebResponse) req.GetResponse ();
122                                 response.Close ();
123
124                                 rs.Close ();
125
126                                 responder.Stop ();
127                         }
128                 }
129
130                 [Test]
131                 [Category("InetAccess")]
132                 public void Cookies1 ()
133                 {
134                         // The purpose of this test is to ensure that the cookies we get from a request
135                         // are stored in both, the CookieCollection in HttpWebResponse and the CookieContainer
136                         // in HttpWebRequest.
137                         // If this URL stops sending *one* and only one cookie, replace it.
138                         string url = "http://www.elmundo.es";
139                         CookieContainer cookies = new CookieContainer ();
140                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
141                         req.KeepAlive = false;
142                         req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv; 1.7.6) Gecko/20050317 Firefox/1.0.2";
143                         req.CookieContainer = cookies;
144                         Assertion.AssertEquals ("#01", 0, cookies.Count);
145                         using (HttpWebResponse res = (HttpWebResponse) req.GetResponse()) {
146                                 CookieCollection coll = req.CookieContainer.GetCookies (new Uri (url));
147                                 Assertion.AssertEquals ("#02", 1, coll.Count);
148                                 Assertion.AssertEquals ("#03", 1, res.Cookies.Count);
149                                 Cookie one = coll [0];
150                                 Cookie two = res.Cookies [0];
151                                 Assertion.AssertEquals ("#04", true, object.ReferenceEquals (one, two));
152                         }
153                 }
154
155 #if !TARGET_JVM //NotWorking
156                 [Test]
157                 public void SslClientBlock ()
158                 {
159                         // This tests that the write request/initread/write body sequence does not hang
160                         // when using SSL.
161                         // If there's a regression for this, the test will hang.
162                         ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
163                         try {
164                                 SslHttpServer server = new SslHttpServer ();
165                                 server.Start ();
166
167                                 string url = String.Format ("https://{0}:{1}/nothing.html", server.IPAddress, server.Port);
168                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
169                                 request.Method = "POST";
170                                 Stream stream = request.GetRequestStream ();
171                                 byte [] bytes = new byte [100];
172                                 stream.Write (bytes, 0, bytes.Length);
173                                 stream.Close ();
174                                 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
175                                 Assertion.AssertEquals ("StatusCode", 200, (int) resp.StatusCode);
176                                 StreamReader sr = new StreamReader (resp.GetResponseStream (), Encoding.UTF8);
177                                 string x = sr.ReadToEnd ();
178                                 sr.Close ();
179                                 resp.Close ();
180                                 server.Stop ();
181                                 if (server.Error != null)
182                                         throw server.Error;
183                         } finally {
184                                 ServicePointManager.CertificatePolicy = null;
185                         }
186                 }
187 #endif
188                 [Test]
189 #if TARGET_JVM
190                 [Category("NotWorking")]
191 #endif
192                 public void Missing_ContentEncoding ()
193                 {
194                         ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
195                         try {
196                                 BadChunkedServer server = new BadChunkedServer ();
197                                 server.Start ();
198
199                                 string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
200                                 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
201                                 request.Method = "GET";
202                                 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
203                                 Assert.AreEqual ("", resp.ContentEncoding);
204                                 resp.Close ();
205                                 server.Stop ();
206                                 if (server.Error != null)
207                                         throw server.Error;
208                         } finally {
209                                 ServicePointManager.CertificatePolicy = null;
210                         }
211                 }
212
213                 [Test]
214 #if TARGET_JVM
215                 [Category ("NotWorking")]
216 #endif
217                 public void BadServer_ChunkedClose ()
218                 {
219                         // The server will send a chunked response without a 'last-chunked' mark
220                         // and then shutdown the socket for sending.
221                         BadChunkedServer server = new BadChunkedServer ();
222                         server.Start ();
223                         string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
224                         HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
225                         HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
226                         string x = null;
227                         try {
228                                 byte [] bytes = new byte [32];
229                                 // Using StreamReader+UTF8Encoding here fails on MS runtime
230                                 Stream stream = resp.GetResponseStream ();
231                                 int nread = stream.Read (bytes, 0, 32);
232                                 Assertion.AssertEquals ("#01", 16, nread);
233                                 x = Encoding.ASCII.GetString (bytes, 0, 16);
234                         } finally {
235                                 resp.Close ();
236                                 server.Stop ();
237                         }
238
239                         if (server.Error != null)
240                                 throw server.Error;
241
242                         Assertion.AssertEquals ("1234567890123456", x);
243                 }
244
245                 [Test]
246                 [Ignore ("This test asserts that our code violates RFC 2616")]
247                 public void MethodCase ()
248                 {
249                         ListDictionary methods = new ListDictionary ();
250 #if NET_2_0
251                         methods.Add ("post", "POST");
252                         methods.Add ("puT", "PUT");
253 #else
254                         methods.Add ("post", "post");
255                         methods.Add ("puT", "puT");
256 #endif
257                         methods.Add ("POST", "POST");
258                         methods.Add ("whatever", "whatever");
259                         methods.Add ("PUT", "PUT");
260
261                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
262                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
263
264                         foreach (DictionaryEntry de in methods) {
265                                 SocketResponder responder = new SocketResponder (new IPEndPoint (IPAddress.Loopback, 8000), 
266                                         new SocketRequestHandler (EchoRequestHandler));
267                                 responder.Start ();
268
269                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
270                                 req.Method = (string) de.Key;
271                                 req.Timeout = 2000;
272                                 req.ReadWriteTimeout = 2000;
273                                 req.KeepAlive = false;
274                                 Stream rs = req.GetRequestStream ();
275                                 rs.Close ();
276                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
277                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
278                                                 Encoding.UTF8);
279                                         string line = sr.ReadLine ();
280                                         sr.Close ();
281                                         Assert.AreEqual (((string) de.Value) + " /test/ HTTP/1.1",
282                                                 line, req.Method);
283                                         resp.Close ();
284                                 }
285                                 responder.Stop ();
286                         }
287                 }
288
289                 [Test]
290                 public void BeginGetRequestStream_Body_NotAllowed ()
291                 {
292                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
293                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
294
295                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
296                                 responder.Start ();
297
298                                 HttpWebRequest request;
299
300                                 request = (HttpWebRequest) WebRequest.Create (url);
301                                 request.Method = "GET";
302
303                                 try {
304                                         request.BeginGetRequestStream (null, null);
305                                         Assert.Fail ("#A1");
306                                 } catch (ProtocolViolationException ex) {
307                                         // Cannot send a content-body with this
308                                         // verb-type
309                                         Assert.IsNull (ex.InnerException, "#A2");
310                                         Assert.IsNotNull (ex.Message, "#A3");
311                                 }
312
313                                 request = (HttpWebRequest) WebRequest.Create (url);
314                                 request.Method = "HEAD";
315
316                                 try {
317                                         request.BeginGetRequestStream (null, null);
318                                         Assert.Fail ("#B1");
319                                 } catch (ProtocolViolationException ex) {
320                                         // Cannot send a content-body with this
321                                         // verb-type
322                                         Assert.IsNull (ex.InnerException, "#B2");
323                                         Assert.IsNotNull (ex.Message, "#B3");
324                                 }
325                         }
326                 }
327
328                 [Test] // bug #465613
329                 [Category ("NotWorking")]
330                 public void BeginGetRequestStream_NoBuffering ()
331                 {
332                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8002);
333                         string url = "http://" + IPAddress.Loopback.ToString () + ":8002/test/";
334
335                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
336                                 responder.Start ();
337
338                                 HttpWebRequest req;
339                                 Stream rs;
340                                 IAsyncResult ar;
341
342                                 req = (HttpWebRequest) WebRequest.Create (url);
343                                 req.Method = "POST";
344                                 req.SendChunked = false;
345                                 req.KeepAlive = false;
346                                 req.AllowWriteStreamBuffering = false;
347
348                                 ar = req.BeginGetRequestStream (null, null);
349                                 rs = req.EndGetRequestStream (ar);
350                                 rs.Close ();
351
352                                 req = (HttpWebRequest) WebRequest.Create (url);
353                                 req.Method = "POST";
354                                 req.SendChunked = false;
355                                 req.KeepAlive = true;
356                                 req.AllowWriteStreamBuffering = false;
357
358                                 try {
359                                         req.BeginGetRequestStream (null, null);
360                                         Assert.Fail ("#A1");
361                                 } catch (ProtocolViolationException ex) {
362                                         // When performing a write operation with
363                                         // AllowWriteStreamBuffering set to false,
364                                         // you must either set ContentLength to a
365                                         // non-negative number or set SendChunked
366                                         // to true
367                                         Assert.IsNull (ex.InnerException, "#A2");
368                                         Assert.IsNotNull (ex.Message, "#A3");
369                                 }
370
371                                 req = (HttpWebRequest) WebRequest.Create (url);
372                                 req.Method = "POST";
373                                 req.SendChunked = false;
374                                 req.KeepAlive = true;
375                                 req.AllowWriteStreamBuffering = false;
376                                 req.ContentLength = 0;
377
378                                 ar = req.BeginGetRequestStream (null, null);
379                                 rs = req.EndGetRequestStream (ar);
380                                 rs.Close ();
381                         }
382                 }
383
384                 [Test] // bug #508027
385                 [Category ("NotWorking")]
386                 public void BeginGetResponse ()
387                 {
388                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8003);
389                         string url = "http://" + IPAddress.Loopback.ToString () + ":8003/test/";
390
391                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
392                                 responder.Start ();
393
394                                 HttpWebRequest req;
395
396                                 req = (HttpWebRequest) WebRequest.Create (url);
397                                 req.Method = "POST";
398                                 req.SendChunked = false;
399                                 req.KeepAlive = false;
400                                 req.AllowWriteStreamBuffering = false;
401                                 req.BeginGetResponse (null, null);
402                                 req.Abort ();
403
404                                 req = (HttpWebRequest) WebRequest.Create (url);
405                                 req.Method = "POST";
406                                 req.SendChunked = true;
407                                 req.KeepAlive = false;
408                                 req.AllowWriteStreamBuffering = false;
409                                 req.BeginGetResponse (null, null);
410                                 req.Abort ();
411
412                                 req = (HttpWebRequest) WebRequest.Create (url);
413                                 req.Method = "POST";
414                                 req.ContentLength = 5;
415                                 req.SendChunked = false;
416                                 req.KeepAlive = false;
417                                 req.AllowWriteStreamBuffering = false;
418                                 req.BeginGetResponse (null, null);
419                                 req.Abort ();
420
421                                 req = (HttpWebRequest) WebRequest.Create (url);
422                                 req.Method = "POST";
423                                 req.SendChunked = false;
424                                 req.KeepAlive = true;
425                                 req.AllowWriteStreamBuffering = false;
426 #if NET_2_0
427                                 req.BeginGetResponse (null, null);
428                                 req.Abort ();
429 #else
430                                 try {
431                                         req.BeginGetResponse (null, null);
432                                 } catch (ProtocolViolationException ex) {
433                                         // Either ContentLength must be set to a non-negative
434                                         // number, or SendChunked set to true in order to perform
435                                         // the write operation when AllowWriteStreamBuffering
436                                         // is disabled
437                                         Assert.IsNull (ex.InnerException, "#A2");
438                                         Assert.IsNotNull (ex.Message, "#A3");
439                                 } finally {
440                                         req.Abort ();
441                                 }
442 #endif
443
444                                 req = (HttpWebRequest) WebRequest.Create (url);
445                                 req.Method = "POST";
446                                 req.SendChunked = false;
447                                 req.KeepAlive = false;
448                                 req.AllowWriteStreamBuffering = false;
449                                 req.ContentLength = 5;
450                                 req.BeginGetResponse (null, null);
451                                 req.Abort ();
452
453                                 req = (HttpWebRequest) WebRequest.Create (url);
454                                 req.Method = "POST";
455                                 req.SendChunked = false;
456                                 req.KeepAlive = true;
457                                 req.AllowWriteStreamBuffering = false;
458                                 req.ContentLength = 5;
459                                 req.BeginGetResponse (null, null);
460                                 req.Abort ();
461
462                                 req = (HttpWebRequest) WebRequest.Create (url);
463                                 req.Method = "GET";
464                                 req.SendChunked = true;
465 #if NET_2_0
466                                 req.BeginGetResponse (null, null);
467                                 req.Abort ();
468 #else
469                                 try {
470                                         req.BeginGetResponse (null, null);
471                                         Assert.Fail ("#B1");
472                                 } catch (ProtocolViolationException ex) {
473                                         // Content-Length cannot be set for a
474                                         // non-write operation
475                                         Assert.IsNull (ex.InnerException, "#B2");
476                                         Assert.IsNotNull (ex.Message, "#B3");
477                                 } finally {
478                                         req.Abort ();
479                                 }
480 #endif
481
482                                 req = (HttpWebRequest) WebRequest.Create (url);
483                                 req.Method = "GET";
484                                 req.ContentLength = 5;
485 #if NET_2_0
486                                 req.BeginGetResponse (null, null);
487                                 req.Abort ();
488 #else
489                                 try {
490                                         req.BeginGetResponse (null, null);
491                                         Assert.Fail ("#C1");
492                                 } catch (ProtocolViolationException ex) {
493                                         // Content-Length cannot be set for a
494                                         // non-write operation
495                                         Assert.IsNull (ex.InnerException, "#C2");
496                                         Assert.IsNotNull (ex.Message, "#C3");
497                                 } finally {
498                                         req.Abort ();
499                                 }
500 #endif
501
502                                 req = (HttpWebRequest) WebRequest.Create (url);
503                                 req.Method = "GET";
504                                 req.ContentLength = 0;
505 #if NET_2_0
506                                 req.BeginGetResponse (null, null);
507                                 req.Abort ();
508 #else
509                                 try {
510                                         req.BeginGetResponse (null, null);
511                                         Assert.Fail ("#D1");
512                                 } catch (ProtocolViolationException ex) {
513                                         // Content-Length cannot be set for a
514                                         // non-write operation
515                                         Assert.IsNull (ex.InnerException, "#D2");
516                                         Assert.IsNotNull (ex.Message, "#D3");
517                                 } finally {
518                                         req.Abort ();
519                                 }
520 #endif
521                         }
522                 }
523
524                 [Test] // bug #429200
525                 public void GetRequestStream ()
526                 {
527                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
528                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
529
530                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
531                                 responder.Start ();
532
533                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
534                                 req.Method = "POST";
535                                 req.Timeout = 2000;
536                                 req.ReadWriteTimeout = 2000;
537
538                                 Stream rs1 = req.GetRequestStream ();
539                                 Stream rs2 = req.GetRequestStream ();
540
541                                 Assert.IsNotNull (rs1, "#1");
542                                 Assert.AreSame (rs1, rs2, "#2");
543
544                                 rs1.Close ();
545                         }
546                 }
547
548                 [Test] // bug #510661
549                 [Category ("NotWorking")]
550                 public void GetRequestStream_Close_NotAllBytesWritten ()
551                 {
552                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
553                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
554
555                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
556                                 responder.Start ();
557
558                                 HttpWebRequest req;
559                                 Stream rs;
560
561                                 req = (HttpWebRequest) WebRequest.Create (url);
562                                 req.Method = "POST";
563                                 req.ContentLength = 2;
564                                 rs = req.GetRequestStream ();
565                                 try {
566                                         rs.Close ();
567                                         Assert.Fail ("#A1");
568                                 } catch (WebException ex) {
569                                         // The request was aborted: The request was canceled
570                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
571                                         Assert.IsNotNull (ex.Message, "#A3");
572                                         Assert.IsNull (ex.Response, "#A4");
573                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#A5");
574
575                                         // Cannot close stream until all bytes are written
576                                         Exception inner = ex.InnerException;
577                                         Assert.IsNotNull (inner, "#A6");
578                                         Assert.AreEqual (typeof (IOException), inner.GetType (), "#A7");
579                                         Assert.IsNull (inner.InnerException, "#A8");
580                                         Assert.IsNotNull (inner.Message, "#A9");
581                                 }
582
583                                 req = (HttpWebRequest) WebRequest.Create (url);
584                                 req.Method = "POST";
585                                 req.ContentLength = 2;
586                                 rs = req.GetRequestStream ();
587                                 rs.WriteByte (0x0d);
588                                 try {
589                                         rs.Close ();
590                                         Assert.Fail ("#B1");
591                                 } catch (WebException ex) {
592                                         // The request was aborted: The request was canceled
593                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
594                                         Assert.IsNotNull (ex.Message, "#B3");
595                                         Assert.IsNull (ex.Response, "#B4");
596                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#B5");
597
598                                         // Cannot close stream until all bytes are written
599                                         Exception inner = ex.InnerException;
600                                         Assert.IsNotNull (inner, "#B6");
601                                         Assert.AreEqual (typeof (IOException), inner.GetType (), "#B7");
602                                         Assert.IsNull (inner.InnerException, "#B8");
603                                         Assert.IsNotNull (inner.Message, "#B9");
604                                 }
605
606                                 req = (HttpWebRequest) WebRequest.Create (url);
607                                 req.Method = "POST";
608                                 req.ContentLength = 2;
609                                 rs = req.GetRequestStream ();
610                                 rs.WriteByte (0x0d);
611                                 rs.WriteByte (0x0d);
612                                 rs.Close ();
613                         }
614                 }
615
616                 [Test] // bug #510642
617                 [Category ("NotWorking")]
618                 public void GetRequestStream_Write_Overflow ()
619                 {
620                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8001);
621                         string url = "http://" + IPAddress.Loopback.ToString () + ":8001/test/";
622
623                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
624                                 responder.Start ();
625
626                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
627                                 req.ProtocolVersion = HttpVersion.Version11;
628                                 req.Method = "POST";
629                                 req.Timeout = 200;
630                                 req.ReadWriteTimeout = 100;
631                                 req.ContentLength = 2;
632
633                                 Stream rs = req.GetRequestStream ();
634
635                                 byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d };
636                                 try {
637                                         rs.Write (buffer, 0, 3);
638                                         Assert.Fail ("#1");
639                                 } catch (ProtocolViolationException ex) {
640                                         // Bytes to be written to the stream exceed
641                                         // Content-Length bytes size specified
642                                         Assert.IsNull (ex.InnerException, "#2");
643                                         Assert.IsNotNull (ex.Message, "#3");
644                                 } finally {
645                                         req.Abort ();
646                                 }
647                         }
648                 }
649
650                 [Test]
651                 [Ignore ("This test asserts that our code violates RFC 2616")]
652                 public void GetRequestStream_Body_NotAllowed ()
653                 {
654                         string [] methods = new string [] { "GET", "HEAD", "CONNECT",
655                                 "get", "HeAd", "ConNect" };
656
657                         foreach (string method in methods) {
658                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
659                                         "http://localhost:8000");
660                                 req.Method = method;
661                                 try {
662                                         req.GetRequestStream ();
663                                         Assert.Fail ("#1:" + method);
664                                 } catch (ProtocolViolationException ex) {
665                                         Assert.AreEqual (typeof (ProtocolViolationException), ex.GetType (), "#2:" + method);
666                                         Assert.IsNull (ex.InnerException, "#3:" + method);
667                                         Assert.IsNotNull (ex.Message, "#4:" + method);
668                                 }
669                         }
670                 }
671
672                 [Test]
673 #if TARGET_JVM
674                 [Category("NotWorking")]
675 #endif
676                 [Ignore ("This does not timeout any more. That's how MS works when reading small responses")]
677                 public void ReadTimeout ()
678                 {
679                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
680                         string url = "http://" + localEP.ToString () + "/original/";
681
682                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
683                                 responder.Start ();
684
685                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
686                                 req.Method = "POST";
687                                 req.AllowAutoRedirect = false;
688                                 req.Timeout = 200;
689                                 req.ReadWriteTimeout = 100;
690                                 req.KeepAlive = false;
691                                 Stream rs = req.GetRequestStream ();
692                                 rs.Close ();
693                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
694                                         try {
695                                                 Stream s = resp.GetResponseStream ();
696                                                 s.ReadByte ();
697                                                 Assert.Fail ("#1");
698                                         } catch (WebException ex) {
699                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
700                                                 Assert.IsNull (ex.InnerException, "#3");
701                                                 Assert.IsNull (ex.Response, "#4");
702                                                 Assert.AreEqual (WebExceptionStatus.Timeout, ex.Status, "#5");
703                                         }
704                                 }
705                                 responder.Stop ();
706                         }
707                 }
708
709                 [Test] // bug #324300
710 #if TARGET_JVM
711                 [Category("NotWorking")]
712 #endif
713                 public void AllowAutoRedirect ()
714                 {
715                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
716                         string url = "http://" + localEP.ToString () + "/original/";
717
718                         // allow autoredirect
719                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
720                                 responder.Start ();
721
722                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
723                                 req.Method = "POST";
724                                 req.Timeout = 2000;
725                                 req.ReadWriteTimeout = 2000;
726                                 req.KeepAlive = false;
727                                 Stream rs = req.GetRequestStream ();
728                                 rs.Close ();
729                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
730                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
731                                                 Encoding.UTF8);
732                                         string body = sr.ReadToEnd ();
733
734                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
735                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
736                                                 localEP.ToString () + "/moved/", "#A2");
737                                         Assert.AreEqual ("GET", resp.Method, "#A3");
738                                         Assert.AreEqual ("LOOKS OK", body, "#A4");
739                                 }
740                                 responder.Stop ();
741                         }
742
743                         // do not allow autoredirect
744                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
745                                 responder.Start ();
746
747                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
748                                 req.Method = "POST";
749                                 req.AllowAutoRedirect = false;
750                                 req.Timeout = 1000;
751                                 req.ReadWriteTimeout = 1000;
752                                 req.KeepAlive = false;
753                                 Stream rs = req.GetRequestStream ();
754                                 rs.Close ();
755                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
756                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.Found, "#B1");
757                                         Assert.AreEqual (url, resp.ResponseUri.ToString (), "#B2");
758                                         Assert.AreEqual ("POST", resp.Method, "#B3");
759                                 }
760                                 responder.Stop ();
761                         }
762                 }
763
764                 [Test] // bug #324347
765                 [Category ("NotWorking")]
766                 public void InternalServerError ()
767                 {
768                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
769                         string url = "http://" + localEP.ToString () + "/original/";
770
771                         // POST
772                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
773                                 responder.Start ();
774
775                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
776                                 req.Method = "POST";
777                                 req.Timeout = 2000;
778                                 req.ReadWriteTimeout = 2000;
779                                 req.KeepAlive = false;
780                                 Stream rs = req.GetRequestStream ();
781                                 rs.Close ();
782
783                                 try {
784                                         req.GetResponse ();
785                                         Assert.Fail ("#A1");
786                                 } catch (WebException ex) {
787                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
788                                         Assert.IsNull (ex.InnerException, "#A3");
789                                         Assert.IsNotNull (ex.Message, "#A4");
790                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A5");
791
792                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
793                                         Assert.IsNotNull (webResponse, "#A6");
794                                         Assert.AreEqual ("POST", webResponse.Method, "#A7");
795                                         webResponse.Close ();
796                                 }
797
798                                 responder.Stop ();
799                         }
800
801                         // GET
802                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
803                                 responder.Start ();
804
805                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
806                                 req.Method = "GET";
807                                 req.Timeout = 2000;
808                                 req.ReadWriteTimeout = 2000;
809                                 req.KeepAlive = false;
810
811                                 try {
812                                         req.GetResponse ();
813                                         Assert.Fail ("#B1");
814                                 } catch (WebException ex) {
815                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
816                                         Assert.IsNull (ex.InnerException, "#B3");
817                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
818
819                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
820                                         Assert.IsNotNull (webResponse, "#B5");
821                                         Assert.AreEqual ("GET", webResponse.Method, "#B6");
822                                         webResponse.Close ();
823                                 }
824
825                                 responder.Stop ();
826                         }
827                 }
828
829                 [Test]
830                 [Category ("NotWorking")] // #B3 fails; we get a SocketException: An existing connection was forcibly closed by the remote host
831                 public void NoContentLength ()
832                 {
833                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
834                         string url = "http://" + localEP.ToString () + "/original/";
835
836                         // POST
837                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
838                                 responder.Start ();
839
840                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
841                                 req.Method = "POST";
842                                 req.Timeout = 2000;
843                                 req.ReadWriteTimeout = 2000;
844                                 req.KeepAlive = false;
845                                 Stream rs = req.GetRequestStream ();
846                                 rs.Close ();
847
848                                 try {
849                                         req.GetResponse ();
850                                         Assert.Fail ("#A1");
851                                 } catch (WebException ex) {
852 #if NET_2_0
853                                         // The underlying connection was closed:
854                                         // An unexpected error occurred on a
855                                         // receive
856                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
857                                         Assert.IsNotNull (ex.InnerException, "#A3");
858                                         Assert.AreEqual (WebExceptionStatus.ReceiveFailure, ex.Status, "#A4");
859                                         Assert.AreEqual (typeof (IOException), ex.InnerException.GetType (), "#A5");
860                                         
861                                         // Unable to read data from the transport connection:
862                                         // A connection attempt failed because the connected party
863                                         // did not properly respond after a period of time, or
864                                         // established connection failed because connected host has
865                                         // failed to respond
866                                         IOException ioe = (IOException) ex.InnerException;
867                                         Assert.IsNotNull (ioe.InnerException, "#A6");
868                                         Assert.IsNotNull (ioe.Message, "#A7");
869                                         Assert.AreEqual (typeof (SocketException), ioe.InnerException.GetType (), "#A8");
870
871                                         // An existing connection was forcibly
872                                         // closed by the remote host
873                                         SocketException soe = (SocketException) ioe.InnerException;
874                                         Assert.IsNull (soe.InnerException, "#A9");
875                                         Assert.IsNotNull (soe.Message, "#A10");
876
877                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
878                                         Assert.IsNull (webResponse, "#A11");
879 #else
880                                         // The remote server returned an error:
881                                         // (500) Internal Server Error
882                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
883                                         Assert.IsNull (ex.InnerException, "#A3");
884                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A4");
885
886                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
887                                         Assert.IsNotNull (webResponse, "#A5");
888                                         Assert.AreEqual ("POST", webResponse.Method, "#A6");
889                                         webResponse.Close ();
890 #endif
891                                 }
892
893                                 responder.Stop ();
894                         }
895
896                         // GET
897                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
898                                 responder.Start ();
899
900                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
901                                 req.Method = "GET";
902                                 req.Timeout = 2000;
903                                 req.ReadWriteTimeout = 2000;
904                                 req.KeepAlive = false;
905
906                                 try {
907                                         req.GetResponse ();
908                                         Assert.Fail ("#B1");
909                                 } catch (WebException ex) {
910                                         // The remote server returned an error:
911                                         // (500) Internal Server Error
912                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
913                                         Assert.IsNull (ex.InnerException, "#B3");
914                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
915
916                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
917                                         Assert.IsNotNull (webResponse, "#B5");
918                                         Assert.AreEqual ("GET", webResponse.Method, "#B6");
919                                         webResponse.Close ();
920                                 }
921
922                                 responder.Stop ();
923                         }
924                 }
925
926                 [Test]
927                 [Category ("NotWorking")] // Assert #2 fails
928                 public void NotModiedSince ()
929                 {
930                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
931                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
932
933                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (NotModifiedSinceHandler))) {
934                                 responder.Start ();
935
936                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
937                                 req.Method = "GET";
938                                 req.KeepAlive = false;
939                                 req.Timeout = 20000;
940                                 req.ReadWriteTimeout = 20000;
941 #if NET_2_0
942                                 req.Headers.Add (HttpRequestHeader.IfNoneMatch, "898bbr2347056cc2e096afc66e104653");
943 #else
944                                 req.Headers.Add ("If-None-Match", "898bbr2347056cc2e096afc66e104653");
945 #endif
946                                 req.IfModifiedSince = new DateTime (2010, 01, 04);
947
948                                 DateTime start = DateTime.Now;
949                                 HttpWebResponse response = null;
950
951                                 try {
952                                         req.GetResponse ();
953                                         Assert.Fail ("#1");
954                                 } catch (WebException e) {
955                                         response = (HttpWebResponse) e.Response;
956                                 }
957
958                                 Assert.IsNotNull (response, "#2");
959                                 using (Stream stream = response.GetResponseStream ()) {
960                                         byte [] buffer = new byte [4096];
961                                         int bytesRead = stream.Read (buffer, 0, buffer.Length);
962                                         Assert.AreEqual (0, bytesRead, "#3");
963                                 }
964
965                                 TimeSpan elapsed = DateTime.Now - start;
966                                 Assert.IsTrue (elapsed.TotalMilliseconds < 2000, "#4");
967
968                                 responder.Stop ();
969                         }
970                 }
971
972 #if NET_2_0
973                 [Test] // bug #324182
974 #if TARGET_JVM
975                 [Category ("NotWorking")]
976 #endif
977                 public void Stream_CanTimeout ()
978                 {
979                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
980                         string url = "http://" + localEP.ToString () + "/original/";
981
982                         // allow autoredirect
983                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
984                                 responder.Start ();
985
986                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
987                                 req.Method = "POST";
988                                 req.Timeout = 2000;
989                                 req.ReadWriteTimeout = 2000;
990                                 req.KeepAlive = false;
991                                 Stream rs = req.GetRequestStream ();
992                                 Assert.IsTrue (rs.CanTimeout, "#1");
993                                 rs.Close ();
994                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
995                                         Stream os = resp.GetResponseStream ();
996                                         Assert.IsTrue (os.CanTimeout, "#2");
997                                         os.Close ();
998                                 }
999                                 responder.Stop ();
1000                         }
1001                 }
1002 #endif
1003
1004                 [Test] // bug #353495
1005                 [Category ("NotWorking")]
1006                 public void LastModifiedKind ()
1007                 {
1008                         const string reqURL = "http://coffeefaq.com/site/node/25";
1009                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create (reqURL);
1010                         HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
1011                         DateTime lastMod = resp.LastModified;
1012                         string rawLastMod = resp.Headers ["Last-Modified"];
1013                         resp.Close ();
1014                         //Assert.AreEqual ("Tue, 15 Jan 2008 08:59:59 GMT", rawLastMod, "#1");
1015 #if NET_2_0
1016                         Assert.AreEqual (DateTimeKind.Local, lastMod.Kind, "#2");
1017 #endif
1018                         req = (HttpWebRequest) WebRequest.Create (reqURL);
1019                         req.IfModifiedSince = lastMod;
1020                         try {
1021                                 resp = (HttpWebResponse) req.GetResponse ();
1022                                 resp.Close ();
1023                                 Assert.Fail ("Should result in 304");
1024                         } catch (WebException ex) {
1025                                 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#3");
1026                                 Assert.AreEqual (((HttpWebResponse) ex.Response).StatusCode, HttpStatusCode.NotModified, "#4");
1027                         }
1028                 }
1029
1030                 static byte [] EchoRequestHandler (Socket socket)
1031                 {
1032                         MemoryStream ms = new MemoryStream ();
1033                         byte [] buffer = new byte [4096];
1034                         int bytesReceived = socket.Receive (buffer);
1035                         while (bytesReceived > 0) {
1036                                 ms.Write (buffer, 0, bytesReceived);
1037                                 if (socket.Available > 0) {
1038                                         bytesReceived = socket.Receive (buffer);
1039                                 } else {
1040                                         bytesReceived = 0;
1041                                 }
1042                         }
1043                         ms.Flush ();
1044                         ms.Position = 0;
1045                         StreamReader sr = new StreamReader (ms, Encoding.UTF8);
1046                         string request = sr.ReadToEnd ();
1047
1048                         StringWriter sw = new StringWriter ();
1049                         sw.WriteLine ("HTTP/1.1 200 OK");
1050                         sw.WriteLine ("Content-Type: text/xml");
1051                         sw.WriteLine ("Content-Length: " + request.Length.ToString (CultureInfo.InvariantCulture));
1052                         sw.WriteLine ();
1053                         sw.Write (request);
1054                         sw.Flush ();
1055
1056                         return Encoding.UTF8.GetBytes (sw.ToString ());
1057                 }
1058
1059                 static byte [] RedirectRequestHandler (Socket socket)
1060                 {
1061                         MemoryStream ms = new MemoryStream ();
1062                         byte [] buffer = new byte [4096];
1063                         int bytesReceived = socket.Receive (buffer);
1064                         while (bytesReceived > 0) {
1065                                 ms.Write (buffer, 0, bytesReceived);
1066                                 if (socket.Available > 0) {
1067                                         bytesReceived = socket.Receive (buffer);
1068                                 } else {
1069                                         bytesReceived = 0;
1070                                 }
1071                         }
1072                         ms.Flush ();
1073                         ms.Position = 0;
1074                         string statusLine = null;
1075                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1076                                 statusLine = sr.ReadLine ();
1077                         }
1078
1079                         StringWriter sw = new StringWriter ();
1080                         if (statusLine.StartsWith ("POST /original/")) {
1081                                 sw.WriteLine ("HTTP/1.0 302 Found");
1082                                 sw.WriteLine ("Location: " + "http://" + IPAddress.Loopback.ToString () + ":8764/moved/");
1083                                 sw.WriteLine ();
1084                                 sw.Flush ();
1085                         } else if (statusLine.StartsWith ("GET /moved/")) {
1086                                 sw.WriteLine ("HTTP/1.0 200 OK");
1087                                 sw.WriteLine ("Content-Type: text/plain");
1088                                 sw.WriteLine ("Content-Length: 8");
1089                                 sw.WriteLine ();
1090                                 sw.Write ("LOOKS OK");
1091                                 sw.Flush ();
1092                         } else {
1093                                 sw.WriteLine ("HTTP/1.0 500 Too Lazy");
1094                                 sw.WriteLine ();
1095                                 sw.Flush ();
1096                         }
1097
1098                         return Encoding.UTF8.GetBytes (sw.ToString ());
1099                 }
1100
1101                 static byte [] InternalErrorHandler (Socket socket)
1102                 {
1103                         StringWriter sw = new StringWriter ();
1104                         sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1105                         sw.WriteLine ("Content-Length: 0");
1106                         sw.WriteLine ();
1107                         sw.Flush ();
1108
1109                         return Encoding.UTF8.GetBytes (sw.ToString ());
1110                 }
1111
1112                 static byte [] NoContentLengthHandler (Socket socket)
1113                 {
1114                         StringWriter sw = new StringWriter ();
1115                         sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1116                         sw.WriteLine ();
1117                         sw.Flush ();
1118
1119                         return Encoding.UTF8.GetBytes (sw.ToString ());
1120                 }
1121
1122                 static byte [] NotModifiedSinceHandler (Socket socket)
1123                 {
1124                         StringWriter sw = new StringWriter ();
1125                         sw.WriteLine ("HTTP/1.1 304 Not Modified");
1126                         sw.WriteLine ("Date: Fri, 06 Feb 2009 12:50:26 GMT");
1127                         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");
1128                         sw.WriteLine ("Not-Modified-Since: Sun, 08 Feb 2009 08:49:26 GMT");
1129                         sw.WriteLine ("ETag: 898bbr2347056cc2e096afc66e104653");
1130                         sw.WriteLine ("Connection: close");
1131                         sw.WriteLine ();
1132                         sw.Flush ();
1133
1134                         return Encoding.UTF8.GetBytes (sw.ToString ());
1135                 }
1136
1137                 [Test]
1138                 public void NtlmAuthentication ()
1139                 {
1140                         NtlmServer server = new NtlmServer ();
1141                         server.Start ();
1142
1143                         string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
1144                         HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
1145                         request.Timeout = 5000;
1146                         request.Credentials = new NetworkCredential ("user", "password", "domain");
1147                         HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
1148                         string res = null;
1149                         using (StreamReader reader = new StreamReader (resp.GetResponseStream ())) {
1150                                 res = reader.ReadToEnd ();      
1151                         }
1152                         resp.Close ();
1153                         server.Stop ();
1154                         Assert.AreEqual ("OK", res);
1155                 }
1156
1157                 class NtlmServer : HttpServer {
1158                         public string Where = "";
1159                         protected override void Run ()
1160                         {
1161                                 Where = "before accept";
1162                                 Socket client = sock.Accept ();
1163                                 NetworkStream ns = new NetworkStream (client, false);
1164                                 StreamReader reader = new StreamReader (ns, Encoding.ASCII);
1165                                 string line;
1166                                 Where = "first read";
1167                                 while ((line = reader.ReadLine ()) != null) {
1168                                         if (line.Trim () == String.Empty) {
1169                                                 break;
1170                                         }
1171                                 }
1172                                 Where = "first write";
1173                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1174                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1175                                                 "WWW-Authenticate: NTLM\r\n" +
1176                                                 "Content-Length: 5\r\n\r\nWRONG");
1177
1178                                 writer.Flush ();
1179                                 Where = "second read";
1180                                 while ((line = reader.ReadLine ()) != null) {
1181                                         if (line.Trim () == String.Empty) {
1182                                                 break;
1183                                         }
1184                                 }
1185                                 Where = "second write";
1186                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1187                                                 "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggAC8GDhqIONH3sAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=\r\n" +
1188                                                 "Content-Length: 5\r\n\r\nWRONG");
1189                                 writer.Flush ();
1190
1191                                 Where = "third read";
1192                                 while ((line = reader.ReadLine ()) != null) {
1193                                         if (line.Trim () == String.Empty) {
1194                                                 break;
1195                                         }
1196                                 }
1197                                 Where = "third write";
1198                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1199                                                 "Keep-Alive: true\r\n" +
1200                                                 "Content-Length: 2\r\n\r\nOK");
1201                                 writer.Flush ();
1202                                 Thread.Sleep (1000);
1203                                 writer.Close ();
1204                                 reader.Close ();
1205                                 client.Close ();
1206                         }
1207                 }
1208
1209                 class BadChunkedServer : HttpServer {
1210                         protected override void Run ()
1211                         {
1212                                 Socket client = sock.Accept ();
1213                                 NetworkStream ns = new NetworkStream (client, true);
1214                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1215                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1216                                                 "Transfer-Encoding: chunked\r\n" +
1217                                                 "Connection: close\r\n" +
1218                                                 "Content-Type: text/plain; charset=UTF-8\r\n\r\n");
1219
1220                                 // This body lacks a 'last-chunk' (see RFC 2616)
1221                                 writer.Write ("10\r\n1234567890123456\r\n");
1222                                 writer.Flush ();
1223                                 client.Shutdown (SocketShutdown.Send);
1224                                 Thread.Sleep (1000);
1225                                 writer.Close ();
1226                         }
1227                 }
1228
1229                 class AcceptAllPolicy : ICertificatePolicy {
1230                         public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
1231                         {
1232                                 return true;
1233                         }
1234                 }
1235
1236                 abstract class HttpServer
1237                 {
1238                         protected Socket sock;
1239                         protected Exception error;
1240                         protected ManualResetEvent evt;
1241
1242                         public HttpServer ()
1243                         {
1244                                 sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1245                                 sock.Bind (new IPEndPoint (IPAddress.Loopback, 0));
1246                                 sock.Listen (1);
1247                         }
1248
1249                         public void Start ()
1250                         {
1251                                 evt = new ManualResetEvent (false);
1252                                 Thread th = new Thread (new ThreadStart (Run));
1253                                 th.Start ();
1254                         }
1255
1256                         public void Stop ()
1257                         {
1258                                 evt.Set ();
1259                                 sock.Close ();
1260                         }
1261                         
1262                         public IPAddress IPAddress {
1263                                 get { return ((IPEndPoint) sock.LocalEndPoint).Address; }
1264                         }
1265                         
1266                         public int Port {
1267                                 get { return ((IPEndPoint) sock.LocalEndPoint).Port; }
1268                         }
1269
1270                         public Exception Error { 
1271                                 get { return error; }
1272                         }
1273
1274                         protected abstract void Run ();
1275                 }
1276
1277 #if !TARGET_JVM
1278                 class SslHttpServer : HttpServer {
1279                         X509Certificate _certificate;
1280
1281                         protected override void Run ()
1282                         {
1283                                 try {
1284                                         Socket client = sock.Accept ();
1285                                         NetworkStream ns = new NetworkStream (client, true);
1286                                         SslServerStream s = new SslServerStream (ns, Certificate, false, false);
1287                                         s.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback (GetPrivateKey);
1288
1289                                         StreamReader reader = new StreamReader (s);
1290                                         StreamWriter writer = new StreamWriter (s, Encoding.ASCII);
1291
1292                                         string line;
1293                                         string hello = "<html><body><h1>Hello World!</h1></body></html>";
1294                                         string answer = "HTTP/1.0 200\r\n" +
1295                                                         "Connection: close\r\n" +
1296                                                         "Content-Type: text/html\r\n" +
1297                                                         "Content-Encoding: " + Encoding.ASCII.WebName + "\r\n" +
1298                                                         "Content-Length: " + hello.Length + "\r\n" +
1299                                                         "\r\n" + hello;
1300
1301                                         // Read the headers
1302                                         do {
1303                                                 line = reader.ReadLine ();
1304                                         } while (line != "" && line != null && line.Length > 0);
1305
1306                                         // Now the content. We know it's 100 bytes.
1307                                         // This makes BeginRead in sslclientstream block.
1308                                         char [] cs = new char [100];
1309                                         reader.Read (cs, 0, 100);
1310
1311                                         writer.Write (answer);
1312                                         writer.Flush ();
1313                                         evt.WaitOne (50000, false);
1314                                 } catch (Exception e) {
1315                                         error = e;
1316                                 }
1317                         }
1318
1319                         X509Certificate Certificate {
1320                                 get {
1321                                         if (_certificate == null)
1322                                                 _certificate = new X509Certificate (CertData.Certificate);
1323
1324                                         return _certificate;
1325                                 }
1326                         }
1327
1328                         AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
1329                         {
1330                                 PrivateKey key = new PrivateKey (CertData.PrivateKey, null);
1331                                 return key.RSA;
1332                         }
1333                 }
1334
1335                 class CertData {
1336                         public readonly static byte [] Certificate = {
1337                                 48, 130, 1, 191, 48, 130, 1, 40, 160, 3, 2, 1, 2, 2, 16, 36, 
1338                                 14, 97, 190, 146, 132, 208, 71, 175, 6, 87, 168, 185, 175, 55, 43, 48, 
1339                                 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 18, 
1340                                 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 111, 110, 122, 97, 
1341                                 108, 111, 48, 30, 23, 13, 48, 53, 48, 54, 50, 50, 49, 57, 51, 48, 
1342                                 52, 54, 90, 23, 13, 51, 57, 49, 50, 51, 49, 50, 51, 53, 57, 53, 
1343                                 57, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 
1344                                 111, 110, 122, 97, 108, 111, 48, 129, 158, 48, 13, 6, 9, 42, 134, 72, 
1345                                 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 140, 0, 48, 129, 136, 2, 
1346                                 129, 129, 0, 138, 9, 38, 25, 166, 252, 59, 26, 39, 184, 128, 216, 38, 
1347                                 73, 41, 86, 30, 228, 160, 205, 41, 135, 115, 223, 44, 62, 42, 198, 178, 
1348                                 190, 81, 11, 25, 21, 216, 49, 179, 130, 246, 52, 97, 175, 212, 94, 157, 
1349                                 231, 162, 66, 161, 103, 63, 204, 83, 141, 172, 119, 97, 225, 206, 98, 101, 
1350                                 210, 106, 2, 206, 81, 90, 173, 47, 41, 199, 209, 241, 177, 177, 96, 207, 
1351                                 254, 220, 190, 66, 180, 153, 0, 209, 14, 178, 69, 194, 3, 37, 116, 239, 
1352                                 49, 23, 185, 245, 255, 126, 35, 85, 246, 56, 244, 107, 117, 24, 14, 57, 
1353                                 9, 111, 147, 189, 220, 142, 57, 104, 153, 193, 205, 19, 14, 22, 157, 16, 
1354                                 24, 80, 201, 2, 2, 0, 17, 163, 23, 48, 21, 48, 19, 6, 3, 85, 
1355                                 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 
1356                                 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3, 
1357                                 129, 129, 0, 64, 49, 57, 253, 218, 198, 229, 51, 189, 12, 154, 225, 183, 
1358                                 160, 147, 90, 113, 172, 69, 122, 28, 77, 97, 215, 231, 194, 150, 29, 196, 
1359                                 65, 95, 218, 99, 142, 111, 79, 205, 109, 76, 32, 92, 220, 76, 88, 53, 
1360                                 237, 80, 11, 85, 44, 91, 21, 210, 12, 34, 223, 234, 18, 187, 136, 62, 
1361                                 26, 240, 103, 180, 12, 226, 221, 250, 247, 129, 51, 23, 129, 165, 56, 67, 
1362                                 43, 83, 244, 110, 207, 24, 253, 195, 16, 46, 80, 113, 80, 18, 2, 254, 
1363                                 120, 147, 151, 164, 23, 210, 230, 100, 19, 197, 179, 28, 194, 48, 106, 159, 
1364                                 155, 144, 37, 82, 44, 160, 40, 52, 146, 174, 77, 188, 160, 230, 75, 172, 
1365                                 123, 3, 254, 
1366                         };
1367
1368                         public readonly static byte [] PrivateKey = {
1369                                 30, 241, 181, 176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 
1370                                 0, 0, 0, 0, 84, 2, 0, 0, 7, 2, 0, 0, 0, 36, 0, 0, 
1371                                 82, 83, 65, 50, 0, 4, 0, 0, 17, 0, 0, 0, 201, 80, 24, 16, 
1372                                 157, 22, 14, 19, 205, 193, 153, 104, 57, 142, 220, 189, 147, 111, 9, 57, 
1373                                 14, 24, 117, 107, 244, 56, 246, 85, 35, 126, 255, 245, 185, 23, 49, 239, 
1374                                 116, 37, 3, 194, 69, 178, 14, 209, 0, 153, 180, 66, 190, 220, 254, 207, 
1375                                 96, 177, 177, 241, 209, 199, 41, 47, 173, 90, 81, 206, 2, 106, 210, 101, 
1376                                 98, 206, 225, 97, 119, 172, 141, 83, 204, 63, 103, 161, 66, 162, 231, 157, 
1377                                 94, 212, 175, 97, 52, 246, 130, 179, 49, 216, 21, 25, 11, 81, 190, 178, 
1378                                 198, 42, 62, 44, 223, 115, 135, 41, 205, 160, 228, 30, 86, 41, 73, 38, 
1379                                 216, 128, 184, 39, 26, 59, 252, 166, 25, 38, 9, 138, 175, 88, 190, 223, 
1380                                 27, 24, 224, 123, 190, 69, 164, 234, 129, 59, 108, 229, 248, 62, 187, 15, 
1381                                 235, 147, 162, 83, 47, 123, 170, 190, 224, 31, 215, 110, 143, 31, 227, 216, 
1382                                 85, 88, 154, 83, 207, 229, 41, 28, 237, 116, 181, 17, 37, 141, 224, 185, 
1383                                 164, 144, 141, 233, 164, 138, 177, 241, 115, 181, 230, 150, 7, 92, 139, 141, 
1384                                 113, 95, 57, 191, 211, 165, 217, 250, 197, 68, 164, 184, 168, 43, 48, 65, 
1385                                 177, 237, 173, 144, 148, 221, 62, 189, 147, 63, 216, 188, 206, 103, 226, 171, 
1386                                 32, 20, 230, 116, 144, 192, 1, 39, 202, 87, 74, 250, 6, 142, 188, 23, 
1387                                 45, 4, 112, 191, 253, 67, 69, 70, 128, 143, 44, 234, 41, 96, 195, 82, 
1388                                 202, 35, 158, 149, 240, 151, 23, 25, 166, 179, 85, 144, 58, 120, 149, 229, 
1389                                 205, 34, 8, 110, 86, 119, 130, 210, 37, 173, 65, 71, 169, 67, 8, 51, 
1390                                 20, 96, 51, 155, 3, 39, 85, 187, 40, 193, 57, 19, 99, 78, 173, 28, 
1391                                 129, 154, 108, 175, 8, 138, 237, 71, 27, 148, 129, 35, 47, 57, 101, 237, 
1392                                 168, 178, 227, 221, 212, 63, 124, 254, 253, 215, 183, 159, 49, 103, 74, 49, 
1393                                 67, 160, 171, 72, 194, 215, 108, 251, 178, 18, 184, 100, 211, 105, 21, 186, 
1394                                 39, 66, 218, 154, 72, 222, 90, 237, 179, 251, 51, 224, 212, 56, 251, 6, 
1395                                 209, 151, 198, 176, 89, 110, 35, 141, 248, 237, 223, 68, 135, 206, 207, 169, 
1396                                 254, 219, 243, 130, 71, 11, 94, 113, 233, 92, 63, 156, 169, 72, 215, 110, 
1397                                 95, 94, 191, 50, 59, 89, 187, 59, 183, 99, 161, 146, 233, 245, 219, 80, 
1398                                 87, 113, 251, 50, 144, 195, 158, 46, 189, 232, 119, 91, 75, 22, 6, 176, 
1399                                 39, 206, 25, 196, 213, 195, 219, 24, 28, 103, 104, 36, 137, 128, 4, 119, 
1400                                 163, 40, 126, 87, 18, 86, 128, 243, 213, 101, 2, 237, 78, 64, 160, 55, 
1401                                 199, 93, 90, 126, 175, 199, 55, 89, 234, 190, 5, 16, 196, 88, 28, 208, 
1402                                 28, 92, 32, 115, 204, 9, 202, 101, 15, 123, 43, 75, 90, 144, 95, 179, 
1403                                 102, 249, 57, 150, 204, 99, 147, 203, 16, 63, 81, 244, 226, 237, 82, 204, 
1404                                 20, 200, 140, 65, 83, 217, 161, 23, 123, 37, 115, 12, 100, 73, 70, 190, 
1405                                 32, 235, 174, 140, 148, 157, 47, 238, 40, 208, 228, 80, 54, 187, 156, 252, 
1406                                 253, 230, 231, 156, 138, 125, 96, 79, 3, 27, 143, 55, 146, 169, 165, 61, 
1407                                 238, 60, 227, 77, 217, 93, 117, 122, 111, 46, 173, 113, 
1408                         };
1409                 }
1410 #endif
1411         }
1412 }