704914741b0144d4899854aa8e06945bc07426a6
[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                 public void BeginGetRequestStream_NoBuffering ()
330                 {
331                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8002);
332                         string url = "http://" + IPAddress.Loopback.ToString () + ":8002/test/";
333
334                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
335                                 responder.Start ();
336
337                                 HttpWebRequest req;
338                                 Stream rs;
339                                 IAsyncResult ar;
340
341                                 req = (HttpWebRequest) WebRequest.Create (url);
342                                 req.Method = "POST";
343                                 req.SendChunked = false;
344                                 req.KeepAlive = false;
345                                 req.AllowWriteStreamBuffering = false;
346
347                                 ar = req.BeginGetRequestStream (null, null);
348                                 rs = req.EndGetRequestStream (ar);
349                                 rs.Close ();
350
351                                 req = (HttpWebRequest) WebRequest.Create (url);
352                                 req.Method = "POST";
353                                 req.SendChunked = false;
354                                 req.KeepAlive = true;
355                                 req.AllowWriteStreamBuffering = false;
356
357                                 try {
358                                         req.BeginGetRequestStream (null, null);
359                                         Assert.Fail ("#A1");
360                                 } catch (ProtocolViolationException ex) {
361                                         // When performing a write operation with
362                                         // AllowWriteStreamBuffering set to false,
363                                         // you must either set ContentLength to a
364                                         // non-negative number or set SendChunked
365                                         // to true
366                                         Assert.IsNull (ex.InnerException, "#A2");
367                                         Assert.IsNotNull (ex.Message, "#A3");
368                                 }
369
370                                 req = (HttpWebRequest) WebRequest.Create (url);
371                                 req.Method = "POST";
372                                 req.SendChunked = false;
373                                 req.KeepAlive = true;
374                                 req.AllowWriteStreamBuffering = false;
375                                 req.ContentLength = 0;
376
377                                 ar = req.BeginGetRequestStream (null, null);
378                                 rs = req.EndGetRequestStream (ar);
379                                 rs.Close ();
380                         }
381                 }
382
383                 [Test] // bug #508027
384                 public void BeginGetResponse ()
385                 {
386                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8003);
387                         string url = "http://" + IPAddress.Loopback.ToString () + ":8003/test/";
388
389                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
390                                 responder.Start ();
391
392                                 HttpWebRequest req;
393
394                                 req = (HttpWebRequest) WebRequest.Create (url);
395                                 req.Method = "POST";
396                                 req.SendChunked = false;
397                                 req.KeepAlive = false;
398                                 req.AllowWriteStreamBuffering = false;
399                                 req.BeginGetResponse (null, null);
400                                 req.Abort ();
401
402                                 req = (HttpWebRequest) WebRequest.Create (url);
403                                 req.Method = "POST";
404                                 req.SendChunked = true;
405                                 req.KeepAlive = false;
406                                 req.AllowWriteStreamBuffering = false;
407                                 req.BeginGetResponse (null, null);
408                                 req.Abort ();
409
410                                 req = (HttpWebRequest) WebRequest.Create (url);
411                                 req.Method = "POST";
412                                 req.ContentLength = 5;
413                                 req.SendChunked = false;
414                                 req.KeepAlive = false;
415                                 req.AllowWriteStreamBuffering = false;
416                                 req.BeginGetResponse (null, null);
417                                 req.Abort ();
418
419                                 req = (HttpWebRequest) WebRequest.Create (url);
420                                 req.Method = "POST";
421                                 req.SendChunked = false;
422                                 req.KeepAlive = true;
423                                 req.AllowWriteStreamBuffering = false;
424 #if NET_2_0
425                                 req.BeginGetResponse (null, null);
426                                 req.Abort ();
427 #else
428                                 try {
429                                         req.BeginGetResponse (null, null);
430                                 } catch (ProtocolViolationException ex) {
431                                         // Either ContentLength must be set to a non-negative
432                                         // number, or SendChunked set to true in order to perform
433                                         // the write operation when AllowWriteStreamBuffering
434                                         // is disabled
435                                         Assert.IsNull (ex.InnerException, "#A2");
436                                         Assert.IsNotNull (ex.Message, "#A3");
437                                 } finally {
438                                         req.Abort ();
439                                 }
440 #endif
441
442                                 req = (HttpWebRequest) WebRequest.Create (url);
443                                 req.Method = "POST";
444                                 req.SendChunked = false;
445                                 req.KeepAlive = false;
446                                 req.AllowWriteStreamBuffering = false;
447                                 req.ContentLength = 5;
448                                 req.BeginGetResponse (null, null);
449                                 req.Abort ();
450
451                                 req = (HttpWebRequest) WebRequest.Create (url);
452                                 req.Method = "POST";
453                                 req.SendChunked = false;
454                                 req.KeepAlive = true;
455                                 req.AllowWriteStreamBuffering = false;
456                                 req.ContentLength = 5;
457                                 req.BeginGetResponse (null, null);
458                                 req.Abort ();
459
460                                 req = (HttpWebRequest) WebRequest.Create (url);
461                                 req.Method = "GET";
462                                 req.SendChunked = true;
463 #if NET_2_0
464                                 req.BeginGetResponse (null, null);
465                                 req.Abort ();
466 #else
467                                 try {
468                                         req.BeginGetResponse (null, null);
469                                         Assert.Fail ("#B1");
470                                 } catch (ProtocolViolationException ex) {
471                                         // Content-Length cannot be set for a
472                                         // non-write operation
473                                         Assert.IsNull (ex.InnerException, "#B2");
474                                         Assert.IsNotNull (ex.Message, "#B3");
475                                 } finally {
476                                         req.Abort ();
477                                 }
478 #endif
479
480                                 req = (HttpWebRequest) WebRequest.Create (url);
481                                 req.Method = "GET";
482                                 req.ContentLength = 5;
483 #if NET_2_0
484                                 req.BeginGetResponse (null, null);
485                                 req.Abort ();
486 #else
487                                 try {
488                                         req.BeginGetResponse (null, null);
489                                         Assert.Fail ("#C1");
490                                 } catch (ProtocolViolationException ex) {
491                                         // Content-Length cannot be set for a
492                                         // non-write operation
493                                         Assert.IsNull (ex.InnerException, "#C2");
494                                         Assert.IsNotNull (ex.Message, "#C3");
495                                 } finally {
496                                         req.Abort ();
497                                 }
498 #endif
499
500                                 req = (HttpWebRequest) WebRequest.Create (url);
501                                 req.Method = "GET";
502                                 req.ContentLength = 0;
503 #if NET_2_0
504                                 req.BeginGetResponse (null, null);
505                                 req.Abort ();
506 #else
507                                 try {
508                                         req.BeginGetResponse (null, null);
509                                         Assert.Fail ("#D1");
510                                 } catch (ProtocolViolationException ex) {
511                                         // Content-Length cannot be set for a
512                                         // non-write operation
513                                         Assert.IsNull (ex.InnerException, "#D2");
514                                         Assert.IsNotNull (ex.Message, "#D3");
515                                 } finally {
516                                         req.Abort ();
517                                 }
518 #endif
519                         }
520                 }
521
522                 [Test] // bug #429200
523                 public void GetRequestStream ()
524                 {
525                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
526                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
527
528                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
529                                 responder.Start ();
530
531                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
532                                 req.Method = "POST";
533                                 req.Timeout = 2000;
534                                 req.ReadWriteTimeout = 2000;
535
536                                 Stream rs1 = req.GetRequestStream ();
537                                 Stream rs2 = req.GetRequestStream ();
538
539                                 Assert.IsNotNull (rs1, "#1");
540                                 Assert.AreSame (rs1, rs2, "#2");
541
542                                 rs1.Close ();
543                         }
544                 }
545
546                 [Test] // bug #510661 and #514996
547                 [Category ("NotWorking")]
548                 public void GetRequestStream_Close_NotAllBytesWritten ()
549                 {
550                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
551                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
552
553                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
554                                 responder.Start ();
555
556                                 HttpWebRequest req;
557                                 Stream rs;
558
559                                 req = (HttpWebRequest) WebRequest.Create (url);
560                                 req.Method = "POST";
561                                 req.ContentLength = 2;
562                                 rs = req.GetRequestStream ();
563                                 try {
564                                         rs.Close ();
565                                         Assert.Fail ("#A1");
566                                 } catch (WebException ex) {
567                                         // The request was aborted: The request was canceled
568                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
569                                         Assert.IsNotNull (ex.Message, "#A3");
570                                         Assert.IsNull (ex.Response, "#A4");
571                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#A5");
572
573                                         // Cannot close stream until all bytes are written
574                                         Exception inner = ex.InnerException;
575                                         Assert.IsNotNull (inner, "#A6");
576                                         Assert.AreEqual (typeof (IOException), inner.GetType (), "#A7");
577                                         Assert.IsNull (inner.InnerException, "#A8");
578                                         Assert.IsNotNull (inner.Message, "#A9");
579                                 }
580
581                                 req = (HttpWebRequest) WebRequest.Create (url);
582                                 req.Method = "POST";
583                                 req.ContentLength = 2;
584                                 rs = req.GetRequestStream ();
585                                 rs.WriteByte (0x0d);
586                                 try {
587                                         rs.Close ();
588                                         Assert.Fail ("#B1");
589                                 } catch (WebException ex) {
590                                         // The request was aborted: The request was canceled
591                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
592                                         Assert.IsNotNull (ex.Message, "#B3");
593                                         Assert.IsNull (ex.Response, "#B4");
594                                         Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#B5");
595
596                                         // Cannot close stream until all bytes are written
597                                         Exception inner = ex.InnerException;
598                                         Assert.IsNotNull (inner, "#B6");
599                                         Assert.AreEqual (typeof (IOException), inner.GetType (), "#B7");
600                                         Assert.IsNull (inner.InnerException, "#B8");
601                                         Assert.IsNotNull (inner.Message, "#B9");
602                                 }
603
604                                 req = (HttpWebRequest) WebRequest.Create (url);
605                                 req.Method = "POST";
606                                 req.ContentLength = 2;
607                                 rs = req.GetRequestStream ();
608                                 rs.WriteByte (0x0d);
609                                 rs.WriteByte (0x0d);
610                                 rs.Close ();
611                         }
612                 }
613
614                 [Test] // bug #510642
615                 public void GetRequestStream_Write_Overflow ()
616                 {
617                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8001);
618                         string url = "http://" + IPAddress.Loopback.ToString () + ":8001/test/";
619
620                         // buffered, non-chunked
621                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
622                                 responder.Start ();
623
624                                 HttpWebRequest req;
625                                 Stream rs;
626                                 byte [] buffer;
627
628                                 req = (HttpWebRequest) WebRequest.Create (url);
629                                 req.ProtocolVersion = HttpVersion.Version11;
630                                 req.Method = "POST";
631                                 req.Timeout = 1000;
632                                 req.ReadWriteTimeout = 100;
633                                 req.ContentLength = 2;
634
635                                 rs = req.GetRequestStream ();
636                                 rs.WriteByte (0x2c);
637
638                                 buffer = new byte [] { 0x2a, 0x1d };
639                                 try {
640                                         rs.Write (buffer, 0, buffer.Length);
641                                         Assert.Fail ("#A1");
642                                 } catch (ProtocolViolationException ex) {
643                                         // Bytes to be written to the stream exceed
644                                         // Content-Length bytes size specified
645                                         Assert.IsNull (ex.InnerException, "#A2");
646                                         Assert.IsNotNull (ex.Message, "#A3");
647                                 } finally {
648                                         req.Abort ();
649                                 }
650
651                                 req = (HttpWebRequest) WebRequest.Create (url);
652                                 req.ProtocolVersion = HttpVersion.Version11;
653                                 req.Method = "POST";
654                                 req.Timeout = 1000;
655                                 req.ReadWriteTimeout = 100;
656                                 req.ContentLength = 2;
657
658                                 rs = req.GetRequestStream ();
659
660                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
661                                 try {
662                                         rs.Write (buffer, 0, buffer.Length);
663                                         Assert.Fail ("#B1");
664                                 } catch (ProtocolViolationException ex) {
665                                         // Bytes to be written to the stream exceed
666                                         // Content-Length bytes size specified
667                                         Assert.IsNull (ex.InnerException, "#B2");
668                                         Assert.IsNotNull (ex.Message, "#B3");
669                                 } finally {
670                                         req.Abort ();
671                                 }
672                         }
673
674                         // buffered, chunked
675                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
676                                 responder.Start ();
677
678                                 HttpWebRequest req;
679                                 Stream rs;
680                                 byte [] buffer;
681
682                                 /*
683                                 req = (HttpWebRequest) WebRequest.Create (url);
684                                 req.ProtocolVersion = HttpVersion.Version11;
685                                 req.Method = "POST";
686                                 req.SendChunked = true;
687                                 req.Timeout = 1000;
688                                 req.ReadWriteTimeout = 100;
689                                 req.ContentLength = 2;
690
691                                 rs = req.GetRequestStream ();
692                                 rs.WriteByte (0x2c);
693
694                                 buffer = new byte [] { 0x2a, 0x1d };
695                                 rs.Write (buffer, 0, buffer.Length);
696                                 req.Abort ();
697                                 */
698
699                                 req = (HttpWebRequest) WebRequest.Create (url);
700                                 req.ProtocolVersion = HttpVersion.Version11;
701                                 req.Method = "POST";
702                                 req.SendChunked = true;
703                                 req.Timeout = 1000;
704                                 req.ReadWriteTimeout = 100;
705                                 req.ContentLength = 2;
706
707                                 rs = req.GetRequestStream ();
708
709                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
710                                 rs.Write (buffer, 0, buffer.Length);
711                                 req.Abort ();
712                         }
713
714                         // non-buffered, non-chunked
715                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
716                                 responder.Start ();
717
718                                 HttpWebRequest req;
719                                 Stream rs;
720                                 byte [] buffer;
721
722                                 req = (HttpWebRequest) WebRequest.Create (url);
723                                 req.AllowWriteStreamBuffering = false;
724                                 req.ProtocolVersion = HttpVersion.Version11;
725                                 req.Method = "POST";
726                                 req.Timeout = 1000;
727                                 req.ReadWriteTimeout = 100;
728                                 req.ContentLength = 2;
729
730                                 rs = req.GetRequestStream ();
731                                 rs.WriteByte (0x2c);
732
733                                 buffer = new byte [] { 0x2a, 0x1d };
734                                 try {
735                                         rs.Write (buffer, 0, buffer.Length);
736                                         Assert.Fail ("#C1");
737                                 } catch (ProtocolViolationException ex) {
738                                         // Bytes to be written to the stream exceed
739                                         // Content-Length bytes size specified
740                                         Assert.IsNull (ex.InnerException, "#C2");
741                                         Assert.IsNotNull (ex.Message, "#3");
742                                 } finally {
743                                         req.Abort ();
744                                 }
745
746                                 req = (HttpWebRequest) WebRequest.Create (url);
747                                 req.AllowWriteStreamBuffering = false;
748                                 req.ProtocolVersion = HttpVersion.Version11;
749                                 req.Method = "POST";
750                                 req.Timeout = 1000;
751                                 req.ReadWriteTimeout = 100;
752                                 req.ContentLength = 2;
753
754                                 rs = req.GetRequestStream ();
755
756                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
757                                 try {
758                                         rs.Write (buffer, 0, buffer.Length);
759                                         Assert.Fail ("#D1");
760                                 } catch (ProtocolViolationException ex) {
761                                         // Bytes to be written to the stream exceed
762                                         // Content-Length bytes size specified
763                                         Assert.IsNull (ex.InnerException, "#D2");
764                                         Assert.IsNotNull (ex.Message, "#D3");
765                                 } finally {
766                                         req.Abort ();
767                                 }
768                         }
769
770                         // non-buffered, chunked
771                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
772                                 responder.Start ();
773
774                                 HttpWebRequest req;
775                                 Stream rs;
776                                 byte [] buffer;
777
778                                 req = (HttpWebRequest) WebRequest.Create (url);
779                                 req.AllowWriteStreamBuffering = false;
780                                 req.ProtocolVersion = HttpVersion.Version11;
781                                 req.Method = "POST";
782                                 req.SendChunked = true;
783                                 req.Timeout = 1000;
784                                 req.ReadWriteTimeout = 100;
785                                 req.ContentLength = 2;
786
787                                 rs = req.GetRequestStream ();
788                                 rs.WriteByte (0x2c);
789
790                                 buffer = new byte [] { 0x2a, 0x1d };
791                                 rs.Write (buffer, 0, buffer.Length);
792                                 req.Abort ();
793
794                                 req = (HttpWebRequest) WebRequest.Create (url);
795                                 req.AllowWriteStreamBuffering = false;
796                                 req.ProtocolVersion = HttpVersion.Version11;
797                                 req.Method = "POST";
798                                 req.SendChunked = true;
799                                 req.Timeout = 1000;
800                                 req.ReadWriteTimeout = 100;
801                                 req.ContentLength = 2;
802
803                                 rs = req.GetRequestStream ();
804
805                                 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
806                                 rs.Write (buffer, 0, buffer.Length);
807                                 req.Abort ();
808                         }
809                 }
810
811                 [Test]
812                 [Ignore ("This test asserts that our code violates RFC 2616")]
813                 public void GetRequestStream_Body_NotAllowed ()
814                 {
815                         string [] methods = new string [] { "GET", "HEAD", "CONNECT",
816                                 "get", "HeAd", "ConNect" };
817
818                         foreach (string method in methods) {
819                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
820                                         "http://localhost:8000");
821                                 req.Method = method;
822                                 try {
823                                         req.GetRequestStream ();
824                                         Assert.Fail ("#1:" + method);
825                                 } catch (ProtocolViolationException ex) {
826                                         Assert.AreEqual (typeof (ProtocolViolationException), ex.GetType (), "#2:" + method);
827                                         Assert.IsNull (ex.InnerException, "#3:" + method);
828                                         Assert.IsNotNull (ex.Message, "#4:" + method);
829                                 }
830                         }
831                 }
832
833                 [Test]
834 #if TARGET_JVM
835                 [Category("NotWorking")]
836 #endif
837                 [Ignore ("This does not timeout any more. That's how MS works when reading small responses")]
838                 public void ReadTimeout ()
839                 {
840                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
841                         string url = "http://" + localEP.ToString () + "/original/";
842
843                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
844                                 responder.Start ();
845
846                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
847                                 req.Method = "POST";
848                                 req.AllowAutoRedirect = false;
849                                 req.Timeout = 200;
850                                 req.ReadWriteTimeout = 100;
851                                 req.KeepAlive = false;
852                                 Stream rs = req.GetRequestStream ();
853                                 rs.Close ();
854                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
855                                         try {
856                                                 Stream s = resp.GetResponseStream ();
857                                                 s.ReadByte ();
858                                                 Assert.Fail ("#1");
859                                         } catch (WebException ex) {
860                                                 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
861                                                 Assert.IsNull (ex.InnerException, "#3");
862                                                 Assert.IsNull (ex.Response, "#4");
863                                                 Assert.AreEqual (WebExceptionStatus.Timeout, ex.Status, "#5");
864                                         }
865                                 }
866                                 responder.Stop ();
867                         }
868                 }
869
870                 [Test] // bug #324300
871 #if TARGET_JVM
872                 [Category("NotWorking")]
873 #endif
874                 public void AllowAutoRedirect ()
875                 {
876                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
877                         string url = "http://" + localEP.ToString () + "/original/";
878
879                         // allow autoredirect
880                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
881                                 responder.Start ();
882
883                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
884                                 req.Method = "POST";
885                                 req.Timeout = 2000;
886                                 req.ReadWriteTimeout = 2000;
887                                 req.KeepAlive = false;
888                                 Stream rs = req.GetRequestStream ();
889                                 rs.Close ();
890                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
891                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
892                                                 Encoding.UTF8);
893                                         string body = sr.ReadToEnd ();
894
895                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
896                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
897                                                 localEP.ToString () + "/moved/", "#A2");
898                                         Assert.AreEqual ("GET", resp.Method, "#A3");
899                                         Assert.AreEqual ("LOOKS OK", body, "#A4");
900                                 }
901                                 responder.Stop ();
902                         }
903
904                         // do not allow autoredirect
905                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
906                                 responder.Start ();
907
908                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
909                                 req.Method = "POST";
910                                 req.AllowAutoRedirect = false;
911                                 req.Timeout = 1000;
912                                 req.ReadWriteTimeout = 1000;
913                                 req.KeepAlive = false;
914                                 Stream rs = req.GetRequestStream ();
915                                 rs.Close ();
916                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
917                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.Found, "#B1");
918                                         Assert.AreEqual (url, resp.ResponseUri.ToString (), "#B2");
919                                         Assert.AreEqual ("POST", resp.Method, "#B3");
920                                 }
921                                 responder.Stop ();
922                         }
923                 }
924
925                 [Test] // bug #324347
926                 [Category ("NotWorking")]
927                 public void InternalServerError ()
928                 {
929                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
930                         string url = "http://" + localEP.ToString () + "/original/";
931
932                         // POST
933                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
934                                 responder.Start ();
935
936                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
937                                 req.Method = "POST";
938                                 req.Timeout = 2000;
939                                 req.ReadWriteTimeout = 2000;
940                                 req.KeepAlive = false;
941                                 Stream rs = req.GetRequestStream ();
942                                 rs.Close ();
943
944                                 try {
945                                         req.GetResponse ();
946                                         Assert.Fail ("#A1");
947                                 } catch (WebException ex) {
948                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
949                                         Assert.IsNull (ex.InnerException, "#A3");
950                                         Assert.IsNotNull (ex.Message, "#A4");
951                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A5");
952
953                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
954                                         Assert.IsNotNull (webResponse, "#A6");
955                                         Assert.AreEqual ("POST", webResponse.Method, "#A7");
956                                         webResponse.Close ();
957                                 }
958
959                                 responder.Stop ();
960                         }
961
962                         // GET
963                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
964                                 responder.Start ();
965
966                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
967                                 req.Method = "GET";
968                                 req.Timeout = 2000;
969                                 req.ReadWriteTimeout = 2000;
970                                 req.KeepAlive = false;
971
972                                 try {
973                                         req.GetResponse ();
974                                         Assert.Fail ("#B1");
975                                 } catch (WebException ex) {
976                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
977                                         Assert.IsNull (ex.InnerException, "#B3");
978                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
979
980                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
981                                         Assert.IsNotNull (webResponse, "#B5");
982                                         Assert.AreEqual ("GET", webResponse.Method, "#B6");
983                                         webResponse.Close ();
984                                 }
985
986                                 responder.Stop ();
987                         }
988                 }
989
990                 [Test]
991                 [Category ("NotWorking")] // #B3 fails; we get a SocketException: An existing connection was forcibly closed by the remote host
992                 public void NoContentLength ()
993                 {
994                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
995                         string url = "http://" + localEP.ToString () + "/original/";
996
997                         // POST
998                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
999                                 responder.Start ();
1000
1001                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1002                                 req.Method = "POST";
1003                                 req.Timeout = 2000;
1004                                 req.ReadWriteTimeout = 2000;
1005                                 req.KeepAlive = false;
1006                                 Stream rs = req.GetRequestStream ();
1007                                 rs.Close ();
1008
1009                                 try {
1010                                         req.GetResponse ();
1011                                         Assert.Fail ("#A1");
1012                                 } catch (WebException ex) {
1013 #if NET_2_0
1014                                         // The underlying connection was closed:
1015                                         // An unexpected error occurred on a
1016                                         // receive
1017                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
1018                                         Assert.IsNotNull (ex.InnerException, "#A3");
1019                                         Assert.AreEqual (WebExceptionStatus.ReceiveFailure, ex.Status, "#A4");
1020                                         Assert.AreEqual (typeof (IOException), ex.InnerException.GetType (), "#A5");
1021                                         
1022                                         // Unable to read data from the transport connection:
1023                                         // A connection attempt failed because the connected party
1024                                         // did not properly respond after a period of time, or
1025                                         // established connection failed because connected host has
1026                                         // failed to respond
1027                                         IOException ioe = (IOException) ex.InnerException;
1028                                         Assert.IsNotNull (ioe.InnerException, "#A6");
1029                                         Assert.IsNotNull (ioe.Message, "#A7");
1030                                         Assert.AreEqual (typeof (SocketException), ioe.InnerException.GetType (), "#A8");
1031
1032                                         // An existing connection was forcibly
1033                                         // closed by the remote host
1034                                         SocketException soe = (SocketException) ioe.InnerException;
1035                                         Assert.IsNull (soe.InnerException, "#A9");
1036                                         Assert.IsNotNull (soe.Message, "#A10");
1037
1038                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1039                                         Assert.IsNull (webResponse, "#A11");
1040 #else
1041                                         // The remote server returned an error:
1042                                         // (500) Internal Server Error
1043                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
1044                                         Assert.IsNull (ex.InnerException, "#A3");
1045                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A4");
1046
1047                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1048                                         Assert.IsNotNull (webResponse, "#A5");
1049                                         Assert.AreEqual ("POST", webResponse.Method, "#A6");
1050                                         webResponse.Close ();
1051 #endif
1052                                 }
1053
1054                                 responder.Stop ();
1055                         }
1056
1057                         // GET
1058                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
1059                                 responder.Start ();
1060
1061                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1062                                 req.Method = "GET";
1063                                 req.Timeout = 2000;
1064                                 req.ReadWriteTimeout = 2000;
1065                                 req.KeepAlive = false;
1066
1067                                 try {
1068                                         req.GetResponse ();
1069                                         Assert.Fail ("#B1");
1070                                 } catch (WebException ex) {
1071                                         // The remote server returned an error:
1072                                         // (500) Internal Server Error
1073                                         Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
1074                                         Assert.IsNull (ex.InnerException, "#B3");
1075                                         Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
1076
1077                                         HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1078                                         Assert.IsNotNull (webResponse, "#B5");
1079                                         Assert.AreEqual ("GET", webResponse.Method, "#B6");
1080                                         webResponse.Close ();
1081                                 }
1082
1083                                 responder.Stop ();
1084                         }
1085                 }
1086
1087                 [Test] // bug #513087
1088                 public void NonStandardVerb ()
1089                 {
1090                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
1091                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/moved/";
1092
1093                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (VerbEchoHandler))) {
1094                                 responder.Start ();
1095
1096                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1097                                 req.Method = "WhatEver";
1098                                 req.KeepAlive = false;
1099                                 req.Timeout = 20000;
1100                                 req.ReadWriteTimeout = 20000;
1101
1102                                 Stream rs = req.GetRequestStream ();
1103                                 rs.Close ();
1104
1105                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1106                                         StreamReader sr = new StreamReader (resp.GetResponseStream (),
1107                                                 Encoding.UTF8);
1108                                         string body = sr.ReadToEnd ();
1109
1110                                         Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#1");
1111                                         Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1112                                                 ep.ToString () + "/moved/", "#2");
1113                                         Assert.AreEqual ("WhatEver", resp.Method, "#3");
1114                                         Assert.AreEqual ("WhatEver", body, "#4");
1115                                 }
1116
1117                                 responder.Stop ();
1118                         }
1119                 }
1120
1121                 [Test]
1122                 [Category ("NotWorking")] // Assert #2 fails
1123                 public void NotModiedSince ()
1124                 {
1125                         IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
1126                         string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
1127
1128                         using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (NotModifiedSinceHandler))) {
1129                                 responder.Start ();
1130
1131                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1132                                 req.Method = "GET";
1133                                 req.KeepAlive = false;
1134                                 req.Timeout = 20000;
1135                                 req.ReadWriteTimeout = 20000;
1136 #if NET_2_0
1137                                 req.Headers.Add (HttpRequestHeader.IfNoneMatch, "898bbr2347056cc2e096afc66e104653");
1138 #else
1139                                 req.Headers.Add ("If-None-Match", "898bbr2347056cc2e096afc66e104653");
1140 #endif
1141                                 req.IfModifiedSince = new DateTime (2010, 01, 04);
1142
1143                                 DateTime start = DateTime.Now;
1144                                 HttpWebResponse response = null;
1145
1146                                 try {
1147                                         req.GetResponse ();
1148                                         Assert.Fail ("#1");
1149                                 } catch (WebException e) {
1150                                         response = (HttpWebResponse) e.Response;
1151                                 }
1152
1153                                 Assert.IsNotNull (response, "#2");
1154                                 using (Stream stream = response.GetResponseStream ()) {
1155                                         byte [] buffer = new byte [4096];
1156                                         int bytesRead = stream.Read (buffer, 0, buffer.Length);
1157                                         Assert.AreEqual (0, bytesRead, "#3");
1158                                 }
1159
1160                                 TimeSpan elapsed = DateTime.Now - start;
1161                                 Assert.IsTrue (elapsed.TotalMilliseconds < 2000, "#4");
1162
1163                                 responder.Stop ();
1164                         }
1165                 }
1166
1167 #if NET_2_0
1168                 [Test] // bug #324182
1169 #if TARGET_JVM
1170                 [Category ("NotWorking")]
1171 #endif
1172                 public void Stream_CanTimeout ()
1173                 {
1174                         IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
1175                         string url = "http://" + localEP.ToString () + "/original/";
1176
1177                         // allow autoredirect
1178                         using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
1179                                 responder.Start ();
1180
1181                                 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1182                                 req.Method = "POST";
1183                                 req.Timeout = 2000;
1184                                 req.ReadWriteTimeout = 2000;
1185                                 req.KeepAlive = false;
1186                                 Stream rs = req.GetRequestStream ();
1187                                 Assert.IsTrue (rs.CanTimeout, "#1");
1188                                 rs.Close ();
1189                                 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1190                                         Stream os = resp.GetResponseStream ();
1191                                         Assert.IsTrue (os.CanTimeout, "#2");
1192                                         os.Close ();
1193                                 }
1194                                 responder.Stop ();
1195                         }
1196                 }
1197 #endif
1198
1199                 [Test] // bug #353495
1200                 [Category ("NotWorking")]
1201                 public void LastModifiedKind ()
1202                 {
1203                         const string reqURL = "http://coffeefaq.com/site/node/25";
1204                         HttpWebRequest req = (HttpWebRequest) WebRequest.Create (reqURL);
1205                         HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
1206                         DateTime lastMod = resp.LastModified;
1207                         string rawLastMod = resp.Headers ["Last-Modified"];
1208                         resp.Close ();
1209                         //Assert.AreEqual ("Tue, 15 Jan 2008 08:59:59 GMT", rawLastMod, "#1");
1210 #if NET_2_0
1211                         Assert.AreEqual (DateTimeKind.Local, lastMod.Kind, "#2");
1212 #endif
1213                         req = (HttpWebRequest) WebRequest.Create (reqURL);
1214                         req.IfModifiedSince = lastMod;
1215                         try {
1216                                 resp = (HttpWebResponse) req.GetResponse ();
1217                                 resp.Close ();
1218                                 Assert.Fail ("Should result in 304");
1219                         } catch (WebException ex) {
1220                                 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#3");
1221                                 Assert.AreEqual (((HttpWebResponse) ex.Response).StatusCode, HttpStatusCode.NotModified, "#4");
1222                         }
1223                 }
1224
1225                 static byte [] EchoRequestHandler (Socket socket)
1226                 {
1227                         MemoryStream ms = new MemoryStream ();
1228                         byte [] buffer = new byte [4096];
1229                         int bytesReceived = socket.Receive (buffer);
1230                         while (bytesReceived > 0) {
1231                                 ms.Write (buffer, 0, bytesReceived);
1232                                 if (socket.Available > 0) {
1233                                         bytesReceived = socket.Receive (buffer);
1234                                 } else {
1235                                         bytesReceived = 0;
1236                                 }
1237                         }
1238                         ms.Flush ();
1239                         ms.Position = 0;
1240                         StreamReader sr = new StreamReader (ms, Encoding.UTF8);
1241                         string request = sr.ReadToEnd ();
1242
1243                         StringWriter sw = new StringWriter ();
1244                         sw.WriteLine ("HTTP/1.1 200 OK");
1245                         sw.WriteLine ("Content-Type: text/xml");
1246                         sw.WriteLine ("Content-Length: " + request.Length.ToString (CultureInfo.InvariantCulture));
1247                         sw.WriteLine ();
1248                         sw.Write (request);
1249                         sw.Flush ();
1250
1251                         return Encoding.UTF8.GetBytes (sw.ToString ());
1252                 }
1253
1254                 static byte [] RedirectRequestHandler (Socket socket)
1255                 {
1256                         MemoryStream ms = new MemoryStream ();
1257                         byte [] buffer = new byte [4096];
1258                         int bytesReceived = socket.Receive (buffer);
1259                         while (bytesReceived > 0) {
1260                                 ms.Write (buffer, 0, bytesReceived);
1261                                 if (socket.Available > 0) {
1262                                         bytesReceived = socket.Receive (buffer);
1263                                 } else {
1264                                         bytesReceived = 0;
1265                                 }
1266                         }
1267                         ms.Flush ();
1268                         ms.Position = 0;
1269                         string statusLine = null;
1270                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1271                                 statusLine = sr.ReadLine ();
1272                         }
1273
1274                         StringWriter sw = new StringWriter ();
1275                         if (statusLine.StartsWith ("POST /original/")) {
1276                                 sw.WriteLine ("HTTP/1.0 302 Found");
1277                                 sw.WriteLine ("Location: " + "http://" + IPAddress.Loopback.ToString () + ":8764/moved/");
1278                                 sw.WriteLine ();
1279                                 sw.Flush ();
1280                         } else if (statusLine.StartsWith ("GET /moved/")) {
1281                                 sw.WriteLine ("HTTP/1.0 200 OK");
1282                                 sw.WriteLine ("Content-Type: text/plain");
1283                                 sw.WriteLine ("Content-Length: 8");
1284                                 sw.WriteLine ();
1285                                 sw.Write ("LOOKS OK");
1286                                 sw.Flush ();
1287                         } else {
1288                                 sw.WriteLine ("HTTP/1.0 500 Too Lazy");
1289                                 sw.WriteLine ();
1290                                 sw.Flush ();
1291                         }
1292
1293                         return Encoding.UTF8.GetBytes (sw.ToString ());
1294                 }
1295
1296                 static byte [] InternalErrorHandler (Socket socket)
1297                 {
1298                         StringWriter sw = new StringWriter ();
1299                         sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1300                         sw.WriteLine ("Content-Length: 0");
1301                         sw.WriteLine ();
1302                         sw.Flush ();
1303
1304                         return Encoding.UTF8.GetBytes (sw.ToString ());
1305                 }
1306
1307                 static byte [] NoContentLengthHandler (Socket socket)
1308                 {
1309                         StringWriter sw = new StringWriter ();
1310                         sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1311                         sw.WriteLine ();
1312                         sw.Flush ();
1313
1314                         return Encoding.UTF8.GetBytes (sw.ToString ());
1315                 }
1316
1317                 static byte [] NotModifiedSinceHandler (Socket socket)
1318                 {
1319                         StringWriter sw = new StringWriter ();
1320                         sw.WriteLine ("HTTP/1.1 304 Not Modified");
1321                         sw.WriteLine ("Date: Fri, 06 Feb 2009 12:50:26 GMT");
1322                         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");
1323                         sw.WriteLine ("Not-Modified-Since: Sun, 08 Feb 2009 08:49:26 GMT");
1324                         sw.WriteLine ("ETag: 898bbr2347056cc2e096afc66e104653");
1325                         sw.WriteLine ("Connection: close");
1326                         sw.WriteLine ();
1327                         sw.Flush ();
1328
1329                         return Encoding.UTF8.GetBytes (sw.ToString ());
1330                 }
1331
1332                 static byte [] VerbEchoHandler (Socket socket)
1333                 {
1334                         MemoryStream ms = new MemoryStream ();
1335                         byte [] buffer = new byte [4096];
1336                         int bytesReceived = socket.Receive (buffer);
1337                         while (bytesReceived > 0) {
1338                                 ms.Write (buffer, 0, bytesReceived);
1339                                 if (socket.Available > 0) {
1340                                         bytesReceived = socket.Receive (buffer);
1341                                 } else {
1342                                         bytesReceived = 0;
1343                                 }
1344                         }
1345                         ms.Flush ();
1346                         ms.Position = 0;
1347                         string statusLine = null;
1348                         using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1349                                 statusLine = sr.ReadLine ();
1350                         }
1351
1352                         string verb = "DEFAULT";
1353                         if (statusLine != null) {
1354                                 string [] parts = statusLine.Split (' ');
1355                                 if (parts.Length > 0)
1356                                         verb = parts [0];
1357                         }
1358
1359                         StringWriter sw = new StringWriter ();
1360                         sw.WriteLine ("HTTP/1.1 200 OK");
1361                         sw.WriteLine ("Content-Type: text/plain");
1362                         sw.WriteLine ("Content-Length: " + verb.Length);
1363                         sw.WriteLine ();
1364                         sw.Write (verb);
1365                         sw.Flush ();
1366
1367                         return Encoding.UTF8.GetBytes (sw.ToString ());
1368                 }
1369
1370                 [Test]
1371                 public void NtlmAuthentication ()
1372                 {
1373                         NtlmServer server = new NtlmServer ();
1374                         server.Start ();
1375
1376                         string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
1377                         HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
1378                         request.Timeout = 5000;
1379                         request.Credentials = new NetworkCredential ("user", "password", "domain");
1380                         HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
1381                         string res = null;
1382                         using (StreamReader reader = new StreamReader (resp.GetResponseStream ())) {
1383                                 res = reader.ReadToEnd ();      
1384                         }
1385                         resp.Close ();
1386                         server.Stop ();
1387                         Assert.AreEqual ("OK", res);
1388                 }
1389
1390                 class NtlmServer : HttpServer {
1391                         public string Where = "";
1392                         protected override void Run ()
1393                         {
1394                                 Where = "before accept";
1395                                 Socket client = sock.Accept ();
1396                                 NetworkStream ns = new NetworkStream (client, false);
1397                                 StreamReader reader = new StreamReader (ns, Encoding.ASCII);
1398                                 string line;
1399                                 Where = "first read";
1400                                 while ((line = reader.ReadLine ()) != null) {
1401                                         if (line.Trim () == String.Empty) {
1402                                                 break;
1403                                         }
1404                                 }
1405                                 Where = "first write";
1406                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1407                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1408                                                 "WWW-Authenticate: NTLM\r\n" +
1409                                                 "Content-Length: 5\r\n\r\nWRONG");
1410
1411                                 writer.Flush ();
1412                                 Where = "second read";
1413                                 while ((line = reader.ReadLine ()) != null) {
1414                                         if (line.Trim () == String.Empty) {
1415                                                 break;
1416                                         }
1417                                 }
1418                                 Where = "second write";
1419                                 writer.Write (  "HTTP/1.1 401 Unauthorized\r\n" +
1420                                                 "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggAC8GDhqIONH3sAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=\r\n" +
1421                                                 "Content-Length: 5\r\n\r\nWRONG");
1422                                 writer.Flush ();
1423
1424                                 Where = "third read";
1425                                 while ((line = reader.ReadLine ()) != null) {
1426                                         if (line.Trim () == String.Empty) {
1427                                                 break;
1428                                         }
1429                                 }
1430                                 Where = "third write";
1431                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1432                                                 "Keep-Alive: true\r\n" +
1433                                                 "Content-Length: 2\r\n\r\nOK");
1434                                 writer.Flush ();
1435                                 Thread.Sleep (1000);
1436                                 writer.Close ();
1437                                 reader.Close ();
1438                                 client.Close ();
1439                         }
1440                 }
1441
1442                 class BadChunkedServer : HttpServer {
1443                         protected override void Run ()
1444                         {
1445                                 Socket client = sock.Accept ();
1446                                 NetworkStream ns = new NetworkStream (client, true);
1447                                 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1448                                 writer.Write (  "HTTP/1.1 200 OK\r\n" +
1449                                                 "Transfer-Encoding: chunked\r\n" +
1450                                                 "Connection: close\r\n" +
1451                                                 "Content-Type: text/plain; charset=UTF-8\r\n\r\n");
1452
1453                                 // This body lacks a 'last-chunk' (see RFC 2616)
1454                                 writer.Write ("10\r\n1234567890123456\r\n");
1455                                 writer.Flush ();
1456                                 client.Shutdown (SocketShutdown.Send);
1457                                 Thread.Sleep (1000);
1458                                 writer.Close ();
1459                         }
1460                 }
1461
1462                 class AcceptAllPolicy : ICertificatePolicy {
1463                         public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
1464                         {
1465                                 return true;
1466                         }
1467                 }
1468
1469                 abstract class HttpServer
1470                 {
1471                         protected Socket sock;
1472                         protected Exception error;
1473                         protected ManualResetEvent evt;
1474
1475                         public HttpServer ()
1476                         {
1477                                 sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1478                                 sock.Bind (new IPEndPoint (IPAddress.Loopback, 0));
1479                                 sock.Listen (1);
1480                         }
1481
1482                         public void Start ()
1483                         {
1484                                 evt = new ManualResetEvent (false);
1485                                 Thread th = new Thread (new ThreadStart (Run));
1486                                 th.Start ();
1487                         }
1488
1489                         public void Stop ()
1490                         {
1491                                 evt.Set ();
1492                                 sock.Close ();
1493                         }
1494                         
1495                         public IPAddress IPAddress {
1496                                 get { return ((IPEndPoint) sock.LocalEndPoint).Address; }
1497                         }
1498                         
1499                         public int Port {
1500                                 get { return ((IPEndPoint) sock.LocalEndPoint).Port; }
1501                         }
1502
1503                         public Exception Error { 
1504                                 get { return error; }
1505                         }
1506
1507                         protected abstract void Run ();
1508                 }
1509
1510 #if !TARGET_JVM
1511                 class SslHttpServer : HttpServer {
1512                         X509Certificate _certificate;
1513
1514                         protected override void Run ()
1515                         {
1516                                 try {
1517                                         Socket client = sock.Accept ();
1518                                         NetworkStream ns = new NetworkStream (client, true);
1519                                         SslServerStream s = new SslServerStream (ns, Certificate, false, false);
1520                                         s.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback (GetPrivateKey);
1521
1522                                         StreamReader reader = new StreamReader (s);
1523                                         StreamWriter writer = new StreamWriter (s, Encoding.ASCII);
1524
1525                                         string line;
1526                                         string hello = "<html><body><h1>Hello World!</h1></body></html>";
1527                                         string answer = "HTTP/1.0 200\r\n" +
1528                                                         "Connection: close\r\n" +
1529                                                         "Content-Type: text/html\r\n" +
1530                                                         "Content-Encoding: " + Encoding.ASCII.WebName + "\r\n" +
1531                                                         "Content-Length: " + hello.Length + "\r\n" +
1532                                                         "\r\n" + hello;
1533
1534                                         // Read the headers
1535                                         do {
1536                                                 line = reader.ReadLine ();
1537                                         } while (line != "" && line != null && line.Length > 0);
1538
1539                                         // Now the content. We know it's 100 bytes.
1540                                         // This makes BeginRead in sslclientstream block.
1541                                         char [] cs = new char [100];
1542                                         reader.Read (cs, 0, 100);
1543
1544                                         writer.Write (answer);
1545                                         writer.Flush ();
1546                                         evt.WaitOne (50000, false);
1547                                 } catch (Exception e) {
1548                                         error = e;
1549                                 }
1550                         }
1551
1552                         X509Certificate Certificate {
1553                                 get {
1554                                         if (_certificate == null)
1555                                                 _certificate = new X509Certificate (CertData.Certificate);
1556
1557                                         return _certificate;
1558                                 }
1559                         }
1560
1561                         AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
1562                         {
1563                                 PrivateKey key = new PrivateKey (CertData.PrivateKey, null);
1564                                 return key.RSA;
1565                         }
1566                 }
1567
1568                 class CertData {
1569                         public readonly static byte [] Certificate = {
1570                                 48, 130, 1, 191, 48, 130, 1, 40, 160, 3, 2, 1, 2, 2, 16, 36, 
1571                                 14, 97, 190, 146, 132, 208, 71, 175, 6, 87, 168, 185, 175, 55, 43, 48, 
1572                                 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 18, 
1573                                 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 111, 110, 122, 97, 
1574                                 108, 111, 48, 30, 23, 13, 48, 53, 48, 54, 50, 50, 49, 57, 51, 48, 
1575                                 52, 54, 90, 23, 13, 51, 57, 49, 50, 51, 49, 50, 51, 53, 57, 53, 
1576                                 57, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 
1577                                 111, 110, 122, 97, 108, 111, 48, 129, 158, 48, 13, 6, 9, 42, 134, 72, 
1578                                 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 140, 0, 48, 129, 136, 2, 
1579                                 129, 129, 0, 138, 9, 38, 25, 166, 252, 59, 26, 39, 184, 128, 216, 38, 
1580                                 73, 41, 86, 30, 228, 160, 205, 41, 135, 115, 223, 44, 62, 42, 198, 178, 
1581                                 190, 81, 11, 25, 21, 216, 49, 179, 130, 246, 52, 97, 175, 212, 94, 157, 
1582                                 231, 162, 66, 161, 103, 63, 204, 83, 141, 172, 119, 97, 225, 206, 98, 101, 
1583                                 210, 106, 2, 206, 81, 90, 173, 47, 41, 199, 209, 241, 177, 177, 96, 207, 
1584                                 254, 220, 190, 66, 180, 153, 0, 209, 14, 178, 69, 194, 3, 37, 116, 239, 
1585                                 49, 23, 185, 245, 255, 126, 35, 85, 246, 56, 244, 107, 117, 24, 14, 57, 
1586                                 9, 111, 147, 189, 220, 142, 57, 104, 153, 193, 205, 19, 14, 22, 157, 16, 
1587                                 24, 80, 201, 2, 2, 0, 17, 163, 23, 48, 21, 48, 19, 6, 3, 85, 
1588                                 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 
1589                                 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3, 
1590                                 129, 129, 0, 64, 49, 57, 253, 218, 198, 229, 51, 189, 12, 154, 225, 183, 
1591                                 160, 147, 90, 113, 172, 69, 122, 28, 77, 97, 215, 231, 194, 150, 29, 196, 
1592                                 65, 95, 218, 99, 142, 111, 79, 205, 109, 76, 32, 92, 220, 76, 88, 53, 
1593                                 237, 80, 11, 85, 44, 91, 21, 210, 12, 34, 223, 234, 18, 187, 136, 62, 
1594                                 26, 240, 103, 180, 12, 226, 221, 250, 247, 129, 51, 23, 129, 165, 56, 67, 
1595                                 43, 83, 244, 110, 207, 24, 253, 195, 16, 46, 80, 113, 80, 18, 2, 254, 
1596                                 120, 147, 151, 164, 23, 210, 230, 100, 19, 197, 179, 28, 194, 48, 106, 159, 
1597                                 155, 144, 37, 82, 44, 160, 40, 52, 146, 174, 77, 188, 160, 230, 75, 172, 
1598                                 123, 3, 254, 
1599                         };
1600
1601                         public readonly static byte [] PrivateKey = {
1602                                 30, 241, 181, 176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 
1603                                 0, 0, 0, 0, 84, 2, 0, 0, 7, 2, 0, 0, 0, 36, 0, 0, 
1604                                 82, 83, 65, 50, 0, 4, 0, 0, 17, 0, 0, 0, 201, 80, 24, 16, 
1605                                 157, 22, 14, 19, 205, 193, 153, 104, 57, 142, 220, 189, 147, 111, 9, 57, 
1606                                 14, 24, 117, 107, 244, 56, 246, 85, 35, 126, 255, 245, 185, 23, 49, 239, 
1607                                 116, 37, 3, 194, 69, 178, 14, 209, 0, 153, 180, 66, 190, 220, 254, 207, 
1608                                 96, 177, 177, 241, 209, 199, 41, 47, 173, 90, 81, 206, 2, 106, 210, 101, 
1609                                 98, 206, 225, 97, 119, 172, 141, 83, 204, 63, 103, 161, 66, 162, 231, 157, 
1610                                 94, 212, 175, 97, 52, 246, 130, 179, 49, 216, 21, 25, 11, 81, 190, 178, 
1611                                 198, 42, 62, 44, 223, 115, 135, 41, 205, 160, 228, 30, 86, 41, 73, 38, 
1612                                 216, 128, 184, 39, 26, 59, 252, 166, 25, 38, 9, 138, 175, 88, 190, 223, 
1613                                 27, 24, 224, 123, 190, 69, 164, 234, 129, 59, 108, 229, 248, 62, 187, 15, 
1614                                 235, 147, 162, 83, 47, 123, 170, 190, 224, 31, 215, 110, 143, 31, 227, 216, 
1615                                 85, 88, 154, 83, 207, 229, 41, 28, 237, 116, 181, 17, 37, 141, 224, 185, 
1616                                 164, 144, 141, 233, 164, 138, 177, 241, 115, 181, 230, 150, 7, 92, 139, 141, 
1617                                 113, 95, 57, 191, 211, 165, 217, 250, 197, 68, 164, 184, 168, 43, 48, 65, 
1618                                 177, 237, 173, 144, 148, 221, 62, 189, 147, 63, 216, 188, 206, 103, 226, 171, 
1619                                 32, 20, 230, 116, 144, 192, 1, 39, 202, 87, 74, 250, 6, 142, 188, 23, 
1620                                 45, 4, 112, 191, 253, 67, 69, 70, 128, 143, 44, 234, 41, 96, 195, 82, 
1621                                 202, 35, 158, 149, 240, 151, 23, 25, 166, 179, 85, 144, 58, 120, 149, 229, 
1622                                 205, 34, 8, 110, 86, 119, 130, 210, 37, 173, 65, 71, 169, 67, 8, 51, 
1623                                 20, 96, 51, 155, 3, 39, 85, 187, 40, 193, 57, 19, 99, 78, 173, 28, 
1624                                 129, 154, 108, 175, 8, 138, 237, 71, 27, 148, 129, 35, 47, 57, 101, 237, 
1625                                 168, 178, 227, 221, 212, 63, 124, 254, 253, 215, 183, 159, 49, 103, 74, 49, 
1626                                 67, 160, 171, 72, 194, 215, 108, 251, 178, 18, 184, 100, 211, 105, 21, 186, 
1627                                 39, 66, 218, 154, 72, 222, 90, 237, 179, 251, 51, 224, 212, 56, 251, 6, 
1628                                 209, 151, 198, 176, 89, 110, 35, 141, 248, 237, 223, 68, 135, 206, 207, 169, 
1629                                 254, 219, 243, 130, 71, 11, 94, 113, 233, 92, 63, 156, 169, 72, 215, 110, 
1630                                 95, 94, 191, 50, 59, 89, 187, 59, 183, 99, 161, 146, 233, 245, 219, 80, 
1631                                 87, 113, 251, 50, 144, 195, 158, 46, 189, 232, 119, 91, 75, 22, 6, 176, 
1632                                 39, 206, 25, 196, 213, 195, 219, 24, 28, 103, 104, 36, 137, 128, 4, 119, 
1633                                 163, 40, 126, 87, 18, 86, 128, 243, 213, 101, 2, 237, 78, 64, 160, 55, 
1634                                 199, 93, 90, 126, 175, 199, 55, 89, 234, 190, 5, 16, 196, 88, 28, 208, 
1635                                 28, 92, 32, 115, 204, 9, 202, 101, 15, 123, 43, 75, 90, 144, 95, 179, 
1636                                 102, 249, 57, 150, 204, 99, 147, 203, 16, 63, 81, 244, 226, 237, 82, 204, 
1637                                 20, 200, 140, 65, 83, 217, 161, 23, 123, 37, 115, 12, 100, 73, 70, 190, 
1638                                 32, 235, 174, 140, 148, 157, 47, 238, 40, 208, 228, 80, 54, 187, 156, 252, 
1639                                 253, 230, 231, 156, 138, 125, 96, 79, 3, 27, 143, 55, 146, 169, 165, 61, 
1640                                 238, 60, 227, 77, 217, 93, 117, 122, 111, 46, 173, 113, 
1641                         };
1642                 }
1643 #endif
1644         }
1645 }