2 // HttpWebRequestTest.cs - NUnit Test Cases for System.Net.HttpWebRequest
5 // Lawrence Pit (loz@cable.a2000.nl)
6 // Martin Willemoes Hansen (mwh@sysrq.dk)
7 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
9 // (C) 2003 Martin Willemoes Hansen
10 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com
13 using NUnit.Framework;
15 using System.Collections;
16 using System.Collections.Specialized;
17 using System.Globalization;
20 using System.Net.Sockets;
21 using System.Security.Cryptography;
22 using System.Security.Cryptography.X509Certificates;
24 using System.Threading;
26 using Mono.Security.Authenticode;
27 using Mono.Security.Protocol.Tls;
30 namespace MonoTests.System.Net
33 public class HttpWebRequestTest
37 [Ignore ("Ignore failures in Sys.Net")]
39 public void Proxy_Null ()
41 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
42 Assert.IsNotNull (req.Proxy, "#1");
45 Assert.IsNull (req.Proxy, "#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");
61 [Category("InetAccess")]
63 [Ignore ("NMA - wrong cookies number returned")]
67 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
68 Assertion.AssertNotNull ("req:If Modified Since: ", req.IfModifiedSince);
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");
74 HttpWebResponse res = (HttpWebResponse) req.GetResponse ();
75 Assert.AreEqual ("OK", res.StatusCode.ToString (), "#B1");
76 Assert.AreEqual ("OK", res.StatusDescription, "#B2");
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");
86 public void AddRange ()
88 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
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"]);
95 req.AddRange ("bits", 2000);
96 Assertion.Fail ("#2");
97 } catch (InvalidOperationException) {}
100 [Test] // bug #471782
101 public void CloseRequestStreamAfterReadingResponse ()
103 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
104 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
106 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
109 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
112 req.ReadWriteTimeout = 2000;
114 byte [] data = new byte [128];
115 req.ContentLength = data.Length;
117 Stream rs = req.GetRequestStream ();
118 rs.Write (data, 0, data.Length);
121 HttpWebResponse response = (HttpWebResponse) req.GetResponse ();
131 [Category("InetAccess")]
132 public void Cookies1 ()
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));
155 #if !TARGET_JVM //NotWorking
157 public void SslClientBlock ()
159 // This tests that the write request/initread/write body sequence does not hang
161 // If there's a regression for this, the test will hang.
162 ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
164 SslHttpServer server = new SslHttpServer ();
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);
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 ();
181 if (server.Error != null)
184 ServicePointManager.CertificatePolicy = null;
190 [Category("NotWorking")]
192 public void Missing_ContentEncoding ()
194 ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
196 BadChunkedServer server = new BadChunkedServer ();
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);
206 if (server.Error != null)
209 ServicePointManager.CertificatePolicy = null;
215 [Category ("NotWorking")]
217 public void BadServer_ChunkedClose ()
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 ();
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 ();
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);
239 if (server.Error != null)
242 Assertion.AssertEquals ("1234567890123456", x);
246 [Ignore ("This test asserts that our code violates RFC 2616")]
247 public void MethodCase ()
249 ListDictionary methods = new ListDictionary ();
251 methods.Add ("post", "POST");
252 methods.Add ("puT", "PUT");
254 methods.Add ("post", "post");
255 methods.Add ("puT", "puT");
257 methods.Add ("POST", "POST");
258 methods.Add ("whatever", "whatever");
259 methods.Add ("PUT", "PUT");
261 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
262 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
264 foreach (DictionaryEntry de in methods) {
265 SocketResponder responder = new SocketResponder (new IPEndPoint (IPAddress.Loopback, 8000),
266 new SocketRequestHandler (EchoRequestHandler));
269 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
270 req.Method = (string) de.Key;
272 req.ReadWriteTimeout = 2000;
273 req.KeepAlive = false;
274 Stream rs = req.GetRequestStream ();
276 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
277 StreamReader sr = new StreamReader (resp.GetResponseStream (),
279 string line = sr.ReadLine ();
281 Assert.AreEqual (((string) de.Value) + " /test/ HTTP/1.1",
290 public void BeginGetRequestStream_Body_NotAllowed ()
292 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
293 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
295 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
298 HttpWebRequest request;
300 request = (HttpWebRequest) WebRequest.Create (url);
301 request.Method = "GET";
304 request.BeginGetRequestStream (null, null);
306 } catch (ProtocolViolationException ex) {
307 // Cannot send a content-body with this
309 Assert.IsNull (ex.InnerException, "#A2");
310 Assert.IsNotNull (ex.Message, "#A3");
313 request = (HttpWebRequest) WebRequest.Create (url);
314 request.Method = "HEAD";
317 request.BeginGetRequestStream (null, null);
319 } catch (ProtocolViolationException ex) {
320 // Cannot send a content-body with this
322 Assert.IsNull (ex.InnerException, "#B2");
323 Assert.IsNotNull (ex.Message, "#B3");
328 [Test] // bug #465613
329 [Category ("NotWorking")]
330 public void BeginGetRequestStream_NoBuffering ()
332 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8002);
333 string url = "http://" + IPAddress.Loopback.ToString () + ":8002/test/";
335 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
342 req = (HttpWebRequest) WebRequest.Create (url);
344 req.SendChunked = false;
345 req.KeepAlive = false;
346 req.AllowWriteStreamBuffering = false;
348 ar = req.BeginGetRequestStream (null, null);
349 rs = req.EndGetRequestStream (ar);
352 req = (HttpWebRequest) WebRequest.Create (url);
354 req.SendChunked = false;
355 req.KeepAlive = true;
356 req.AllowWriteStreamBuffering = false;
359 req.BeginGetRequestStream (null, null);
361 } catch (ProtocolViolationException ex) {
362 // When performing a write operation with
363 // AllowWriteStreamBuffering set to false,
364 // you must either set ContentLength to a
365 // non-negative number or set SendChunked
367 Assert.IsNull (ex.InnerException, "#A2");
368 Assert.IsNotNull (ex.Message, "#A3");
371 req = (HttpWebRequest) WebRequest.Create (url);
373 req.SendChunked = false;
374 req.KeepAlive = true;
375 req.AllowWriteStreamBuffering = false;
376 req.ContentLength = 0;
378 ar = req.BeginGetRequestStream (null, null);
379 rs = req.EndGetRequestStream (ar);
384 [Test] // bug #508027
385 [Category ("NotWorking")]
386 public void BeginGetResponse ()
388 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8003);
389 string url = "http://" + IPAddress.Loopback.ToString () + ":8003/test/";
391 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
396 req = (HttpWebRequest) WebRequest.Create (url);
398 req.SendChunked = false;
399 req.KeepAlive = false;
400 req.AllowWriteStreamBuffering = false;
401 req.BeginGetResponse (null, null);
404 req = (HttpWebRequest) WebRequest.Create (url);
406 req.SendChunked = true;
407 req.KeepAlive = false;
408 req.AllowWriteStreamBuffering = false;
409 req.BeginGetResponse (null, null);
412 req = (HttpWebRequest) WebRequest.Create (url);
414 req.ContentLength = 5;
415 req.SendChunked = false;
416 req.KeepAlive = false;
417 req.AllowWriteStreamBuffering = false;
418 req.BeginGetResponse (null, null);
421 req = (HttpWebRequest) WebRequest.Create (url);
423 req.SendChunked = false;
424 req.KeepAlive = true;
425 req.AllowWriteStreamBuffering = false;
427 req.BeginGetResponse (null, null);
431 req.BeginGetResponse (null, null);
432 } catch (ProtocolViolationException ex) {
433 // Either ContentLength must be set to a non-negative
434 // number, or SendChunked set to true in order to perform
435 // the write operation when AllowWriteStreamBuffering
437 Assert.IsNull (ex.InnerException, "#A2");
438 Assert.IsNotNull (ex.Message, "#A3");
444 req = (HttpWebRequest) WebRequest.Create (url);
446 req.SendChunked = false;
447 req.KeepAlive = false;
448 req.AllowWriteStreamBuffering = false;
449 req.ContentLength = 5;
450 req.BeginGetResponse (null, null);
453 req = (HttpWebRequest) WebRequest.Create (url);
455 req.SendChunked = false;
456 req.KeepAlive = true;
457 req.AllowWriteStreamBuffering = false;
458 req.ContentLength = 5;
459 req.BeginGetResponse (null, null);
462 req = (HttpWebRequest) WebRequest.Create (url);
464 req.SendChunked = true;
466 req.BeginGetResponse (null, null);
470 req.BeginGetResponse (null, null);
472 } catch (ProtocolViolationException ex) {
473 // Content-Length cannot be set for a
474 // non-write operation
475 Assert.IsNull (ex.InnerException, "#B2");
476 Assert.IsNotNull (ex.Message, "#B3");
482 req = (HttpWebRequest) WebRequest.Create (url);
484 req.ContentLength = 5;
486 req.BeginGetResponse (null, null);
490 req.BeginGetResponse (null, null);
492 } catch (ProtocolViolationException ex) {
493 // Content-Length cannot be set for a
494 // non-write operation
495 Assert.IsNull (ex.InnerException, "#C2");
496 Assert.IsNotNull (ex.Message, "#C3");
502 req = (HttpWebRequest) WebRequest.Create (url);
504 req.ContentLength = 0;
506 req.BeginGetResponse (null, null);
510 req.BeginGetResponse (null, null);
512 } catch (ProtocolViolationException ex) {
513 // Content-Length cannot be set for a
514 // non-write operation
515 Assert.IsNull (ex.InnerException, "#D2");
516 Assert.IsNotNull (ex.Message, "#D3");
524 [Test] // bug #429200
525 public void GetRequestStream ()
527 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
528 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
530 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
533 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
536 req.ReadWriteTimeout = 2000;
538 Stream rs1 = req.GetRequestStream ();
539 Stream rs2 = req.GetRequestStream ();
541 Assert.IsNotNull (rs1, "#1");
542 Assert.AreSame (rs1, rs2, "#2");
548 [Test] // bug #510661
549 [Category ("NotWorking")]
550 public void GetRequestStream_Close_NotAllBytesWritten ()
552 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
553 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
555 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
561 req = (HttpWebRequest) WebRequest.Create (url);
563 req.ContentLength = 2;
564 rs = req.GetRequestStream ();
568 } catch (WebException ex) {
569 // The request was aborted: The request was canceled
570 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
571 Assert.IsNotNull (ex.Message, "#A3");
572 Assert.IsNull (ex.Response, "#A4");
573 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#A5");
575 // Cannot close stream until all bytes are written
576 Exception inner = ex.InnerException;
577 Assert.IsNotNull (inner, "#A6");
578 Assert.AreEqual (typeof (IOException), inner.GetType (), "#A7");
579 Assert.IsNull (inner.InnerException, "#A8");
580 Assert.IsNotNull (inner.Message, "#A9");
583 req = (HttpWebRequest) WebRequest.Create (url);
585 req.ContentLength = 2;
586 rs = req.GetRequestStream ();
591 } catch (WebException ex) {
592 // The request was aborted: The request was canceled
593 Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
594 Assert.IsNotNull (ex.Message, "#B3");
595 Assert.IsNull (ex.Response, "#B4");
596 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#B5");
598 // Cannot close stream until all bytes are written
599 Exception inner = ex.InnerException;
600 Assert.IsNotNull (inner, "#B6");
601 Assert.AreEqual (typeof (IOException), inner.GetType (), "#B7");
602 Assert.IsNull (inner.InnerException, "#B8");
603 Assert.IsNotNull (inner.Message, "#B9");
606 req = (HttpWebRequest) WebRequest.Create (url);
608 req.ContentLength = 2;
609 rs = req.GetRequestStream ();
616 [Test] // bug #510642
617 [Category ("NotWorking")]
618 public void GetRequestStream_Write_Overflow ()
620 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8001);
621 string url = "http://" + IPAddress.Loopback.ToString () + ":8001/test/";
623 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
626 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
627 req.ProtocolVersion = HttpVersion.Version11;
630 req.ReadWriteTimeout = 100;
631 req.ContentLength = 2;
633 Stream rs = req.GetRequestStream ();
635 byte [] buffer = new byte [] { 0x2a, 0x2c, 0x1d };
637 rs.Write (buffer, 0, 3);
639 } catch (ProtocolViolationException ex) {
640 // Bytes to be written to the stream exceed
641 // Content-Length bytes size specified
642 Assert.IsNull (ex.InnerException, "#2");
643 Assert.IsNotNull (ex.Message, "#3");
651 [Ignore ("This test asserts that our code violates RFC 2616")]
652 public void GetRequestStream_Body_NotAllowed ()
654 string [] methods = new string [] { "GET", "HEAD", "CONNECT",
655 "get", "HeAd", "ConNect" };
657 foreach (string method in methods) {
658 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
659 "http://localhost:8000");
662 req.GetRequestStream ();
663 Assert.Fail ("#1:" + method);
664 } catch (ProtocolViolationException ex) {
665 Assert.AreEqual (typeof (ProtocolViolationException), ex.GetType (), "#2:" + method);
666 Assert.IsNull (ex.InnerException, "#3:" + method);
667 Assert.IsNotNull (ex.Message, "#4:" + method);
674 [Category("NotWorking")]
676 [Ignore ("This does not timeout any more. That's how MS works when reading small responses")]
677 public void ReadTimeout ()
679 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
680 string url = "http://" + localEP.ToString () + "/original/";
682 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
685 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
687 req.AllowAutoRedirect = false;
689 req.ReadWriteTimeout = 100;
690 req.KeepAlive = false;
691 Stream rs = req.GetRequestStream ();
693 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
695 Stream s = resp.GetResponseStream ();
698 } catch (WebException ex) {
699 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
700 Assert.IsNull (ex.InnerException, "#3");
701 Assert.IsNull (ex.Response, "#4");
702 Assert.AreEqual (WebExceptionStatus.Timeout, ex.Status, "#5");
709 [Test] // bug #324300
711 [Category("NotWorking")]
713 public void AllowAutoRedirect ()
715 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
716 string url = "http://" + localEP.ToString () + "/original/";
718 // allow autoredirect
719 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
722 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
725 req.ReadWriteTimeout = 2000;
726 req.KeepAlive = false;
727 Stream rs = req.GetRequestStream ();
729 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
730 StreamReader sr = new StreamReader (resp.GetResponseStream (),
732 string body = sr.ReadToEnd ();
734 Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
735 Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
736 localEP.ToString () + "/moved/", "#A2");
737 Assert.AreEqual ("GET", resp.Method, "#A3");
738 Assert.AreEqual ("LOOKS OK", body, "#A4");
743 // do not allow autoredirect
744 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
747 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
749 req.AllowAutoRedirect = false;
751 req.ReadWriteTimeout = 1000;
752 req.KeepAlive = false;
753 Stream rs = req.GetRequestStream ();
755 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
756 Assert.AreEqual (resp.StatusCode, HttpStatusCode.Found, "#B1");
757 Assert.AreEqual (url, resp.ResponseUri.ToString (), "#B2");
758 Assert.AreEqual ("POST", resp.Method, "#B3");
764 [Test] // bug #324347
765 [Category ("NotWorking")]
766 public void InternalServerError ()
768 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
769 string url = "http://" + localEP.ToString () + "/original/";
772 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
775 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
778 req.ReadWriteTimeout = 2000;
779 req.KeepAlive = false;
780 Stream rs = req.GetRequestStream ();
786 } catch (WebException ex) {
787 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
788 Assert.IsNull (ex.InnerException, "#A3");
789 Assert.IsNotNull (ex.Message, "#A4");
790 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A5");
792 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
793 Assert.IsNotNull (webResponse, "#A6");
794 Assert.AreEqual ("POST", webResponse.Method, "#A7");
795 webResponse.Close ();
802 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
805 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
808 req.ReadWriteTimeout = 2000;
809 req.KeepAlive = false;
814 } catch (WebException ex) {
815 Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
816 Assert.IsNull (ex.InnerException, "#B3");
817 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
819 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
820 Assert.IsNotNull (webResponse, "#B5");
821 Assert.AreEqual ("GET", webResponse.Method, "#B6");
822 webResponse.Close ();
830 [Category ("NotWorking")] // #B3 fails; we get a SocketException: An existing connection was forcibly closed by the remote host
831 public void NoContentLength ()
833 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
834 string url = "http://" + localEP.ToString () + "/original/";
837 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
840 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
843 req.ReadWriteTimeout = 2000;
844 req.KeepAlive = false;
845 Stream rs = req.GetRequestStream ();
851 } catch (WebException ex) {
853 // The underlying connection was closed:
854 // An unexpected error occurred on a
856 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
857 Assert.IsNotNull (ex.InnerException, "#A3");
858 Assert.AreEqual (WebExceptionStatus.ReceiveFailure, ex.Status, "#A4");
859 Assert.AreEqual (typeof (IOException), ex.InnerException.GetType (), "#A5");
861 // Unable to read data from the transport connection:
862 // A connection attempt failed because the connected party
863 // did not properly respond after a period of time, or
864 // established connection failed because connected host has
866 IOException ioe = (IOException) ex.InnerException;
867 Assert.IsNotNull (ioe.InnerException, "#A6");
868 Assert.IsNotNull (ioe.Message, "#A7");
869 Assert.AreEqual (typeof (SocketException), ioe.InnerException.GetType (), "#A8");
871 // An existing connection was forcibly
872 // closed by the remote host
873 SocketException soe = (SocketException) ioe.InnerException;
874 Assert.IsNull (soe.InnerException, "#A9");
875 Assert.IsNotNull (soe.Message, "#A10");
877 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
878 Assert.IsNull (webResponse, "#A11");
880 // The remote server returned an error:
881 // (500) Internal Server Error
882 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
883 Assert.IsNull (ex.InnerException, "#A3");
884 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A4");
886 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
887 Assert.IsNotNull (webResponse, "#A5");
888 Assert.AreEqual ("POST", webResponse.Method, "#A6");
889 webResponse.Close ();
897 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
900 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
903 req.ReadWriteTimeout = 2000;
904 req.KeepAlive = false;
909 } catch (WebException ex) {
910 // The remote server returned an error:
911 // (500) Internal Server Error
912 Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
913 Assert.IsNull (ex.InnerException, "#B3");
914 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
916 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
917 Assert.IsNotNull (webResponse, "#B5");
918 Assert.AreEqual ("GET", webResponse.Method, "#B6");
919 webResponse.Close ();
927 [Category ("NotWorking")] // Assert #2 fails
928 public void NotModiedSince ()
930 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
931 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
933 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (NotModifiedSinceHandler))) {
936 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
938 req.KeepAlive = false;
940 req.ReadWriteTimeout = 20000;
942 req.Headers.Add (HttpRequestHeader.IfNoneMatch, "898bbr2347056cc2e096afc66e104653");
944 req.Headers.Add ("If-None-Match", "898bbr2347056cc2e096afc66e104653");
946 req.IfModifiedSince = new DateTime (2010, 01, 04);
948 DateTime start = DateTime.Now;
949 HttpWebResponse response = null;
954 } catch (WebException e) {
955 response = (HttpWebResponse) e.Response;
958 Assert.IsNotNull (response, "#2");
959 using (Stream stream = response.GetResponseStream ()) {
960 byte [] buffer = new byte [4096];
961 int bytesRead = stream.Read (buffer, 0, buffer.Length);
962 Assert.AreEqual (0, bytesRead, "#3");
965 TimeSpan elapsed = DateTime.Now - start;
966 Assert.IsTrue (elapsed.TotalMilliseconds < 2000, "#4");
973 [Test] // bug #324182
975 [Category ("NotWorking")]
977 public void Stream_CanTimeout ()
979 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
980 string url = "http://" + localEP.ToString () + "/original/";
982 // allow autoredirect
983 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
986 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
989 req.ReadWriteTimeout = 2000;
990 req.KeepAlive = false;
991 Stream rs = req.GetRequestStream ();
992 Assert.IsTrue (rs.CanTimeout, "#1");
994 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
995 Stream os = resp.GetResponseStream ();
996 Assert.IsTrue (os.CanTimeout, "#2");
1004 [Test] // bug #353495
1005 [Category ("NotWorking")]
1006 public void LastModifiedKind ()
1008 const string reqURL = "http://coffeefaq.com/site/node/25";
1009 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (reqURL);
1010 HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
1011 DateTime lastMod = resp.LastModified;
1012 string rawLastMod = resp.Headers ["Last-Modified"];
1014 //Assert.AreEqual ("Tue, 15 Jan 2008 08:59:59 GMT", rawLastMod, "#1");
1016 Assert.AreEqual (DateTimeKind.Local, lastMod.Kind, "#2");
1018 req = (HttpWebRequest) WebRequest.Create (reqURL);
1019 req.IfModifiedSince = lastMod;
1021 resp = (HttpWebResponse) req.GetResponse ();
1023 Assert.Fail ("Should result in 304");
1024 } catch (WebException ex) {
1025 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#3");
1026 Assert.AreEqual (((HttpWebResponse) ex.Response).StatusCode, HttpStatusCode.NotModified, "#4");
1030 static byte [] EchoRequestHandler (Socket socket)
1032 MemoryStream ms = new MemoryStream ();
1033 byte [] buffer = new byte [4096];
1034 int bytesReceived = socket.Receive (buffer);
1035 while (bytesReceived > 0) {
1036 ms.Write (buffer, 0, bytesReceived);
1037 if (socket.Available > 0) {
1038 bytesReceived = socket.Receive (buffer);
1045 StreamReader sr = new StreamReader (ms, Encoding.UTF8);
1046 string request = sr.ReadToEnd ();
1048 StringWriter sw = new StringWriter ();
1049 sw.WriteLine ("HTTP/1.1 200 OK");
1050 sw.WriteLine ("Content-Type: text/xml");
1051 sw.WriteLine ("Content-Length: " + request.Length.ToString (CultureInfo.InvariantCulture));
1056 return Encoding.UTF8.GetBytes (sw.ToString ());
1059 static byte [] RedirectRequestHandler (Socket socket)
1061 MemoryStream ms = new MemoryStream ();
1062 byte [] buffer = new byte [4096];
1063 int bytesReceived = socket.Receive (buffer);
1064 while (bytesReceived > 0) {
1065 ms.Write (buffer, 0, bytesReceived);
1066 if (socket.Available > 0) {
1067 bytesReceived = socket.Receive (buffer);
1074 string statusLine = null;
1075 using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1076 statusLine = sr.ReadLine ();
1079 StringWriter sw = new StringWriter ();
1080 if (statusLine.StartsWith ("POST /original/")) {
1081 sw.WriteLine ("HTTP/1.0 302 Found");
1082 sw.WriteLine ("Location: " + "http://" + IPAddress.Loopback.ToString () + ":8764/moved/");
1085 } else if (statusLine.StartsWith ("GET /moved/")) {
1086 sw.WriteLine ("HTTP/1.0 200 OK");
1087 sw.WriteLine ("Content-Type: text/plain");
1088 sw.WriteLine ("Content-Length: 8");
1090 sw.Write ("LOOKS OK");
1093 sw.WriteLine ("HTTP/1.0 500 Too Lazy");
1098 return Encoding.UTF8.GetBytes (sw.ToString ());
1101 static byte [] InternalErrorHandler (Socket socket)
1103 StringWriter sw = new StringWriter ();
1104 sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1105 sw.WriteLine ("Content-Length: 0");
1109 return Encoding.UTF8.GetBytes (sw.ToString ());
1112 static byte [] NoContentLengthHandler (Socket socket)
1114 StringWriter sw = new StringWriter ();
1115 sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1119 return Encoding.UTF8.GetBytes (sw.ToString ());
1122 static byte [] NotModifiedSinceHandler (Socket socket)
1124 StringWriter sw = new StringWriter ();
1125 sw.WriteLine ("HTTP/1.1 304 Not Modified");
1126 sw.WriteLine ("Date: Fri, 06 Feb 2009 12:50:26 GMT");
1127 sw.WriteLine ("Server: Apache/2.2.6 (Debian) PHP/5.2.6-2+b1 with Suhosin-Patch mod_ssl/2.2.6 OpenSSL/0.9.8g");
1128 sw.WriteLine ("Not-Modified-Since: Sun, 08 Feb 2009 08:49:26 GMT");
1129 sw.WriteLine ("ETag: 898bbr2347056cc2e096afc66e104653");
1130 sw.WriteLine ("Connection: close");
1134 return Encoding.UTF8.GetBytes (sw.ToString ());
1138 public void NtlmAuthentication ()
1140 NtlmServer server = new NtlmServer ();
1143 string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
1144 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
1145 request.Timeout = 5000;
1146 request.Credentials = new NetworkCredential ("user", "password", "domain");
1147 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
1149 using (StreamReader reader = new StreamReader (resp.GetResponseStream ())) {
1150 res = reader.ReadToEnd ();
1154 Assert.AreEqual ("OK", res);
1157 class NtlmServer : HttpServer {
1158 public string Where = "";
1159 protected override void Run ()
1161 Where = "before accept";
1162 Socket client = sock.Accept ();
1163 NetworkStream ns = new NetworkStream (client, false);
1164 StreamReader reader = new StreamReader (ns, Encoding.ASCII);
1166 Where = "first read";
1167 while ((line = reader.ReadLine ()) != null) {
1168 if (line.Trim () == String.Empty) {
1172 Where = "first write";
1173 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1174 writer.Write ( "HTTP/1.1 401 Unauthorized\r\n" +
1175 "WWW-Authenticate: NTLM\r\n" +
1176 "Content-Length: 5\r\n\r\nWRONG");
1179 Where = "second read";
1180 while ((line = reader.ReadLine ()) != null) {
1181 if (line.Trim () == String.Empty) {
1185 Where = "second write";
1186 writer.Write ( "HTTP/1.1 401 Unauthorized\r\n" +
1187 "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggAC8GDhqIONH3sAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=\r\n" +
1188 "Content-Length: 5\r\n\r\nWRONG");
1191 Where = "third read";
1192 while ((line = reader.ReadLine ()) != null) {
1193 if (line.Trim () == String.Empty) {
1197 Where = "third write";
1198 writer.Write ( "HTTP/1.1 200 OK\r\n" +
1199 "Keep-Alive: true\r\n" +
1200 "Content-Length: 2\r\n\r\nOK");
1202 Thread.Sleep (1000);
1209 class BadChunkedServer : HttpServer {
1210 protected override void Run ()
1212 Socket client = sock.Accept ();
1213 NetworkStream ns = new NetworkStream (client, true);
1214 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1215 writer.Write ( "HTTP/1.1 200 OK\r\n" +
1216 "Transfer-Encoding: chunked\r\n" +
1217 "Connection: close\r\n" +
1218 "Content-Type: text/plain; charset=UTF-8\r\n\r\n");
1220 // This body lacks a 'last-chunk' (see RFC 2616)
1221 writer.Write ("10\r\n1234567890123456\r\n");
1223 client.Shutdown (SocketShutdown.Send);
1224 Thread.Sleep (1000);
1229 class AcceptAllPolicy : ICertificatePolicy {
1230 public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
1236 abstract class HttpServer
1238 protected Socket sock;
1239 protected Exception error;
1240 protected ManualResetEvent evt;
1242 public HttpServer ()
1244 sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1245 sock.Bind (new IPEndPoint (IPAddress.Loopback, 0));
1249 public void Start ()
1251 evt = new ManualResetEvent (false);
1252 Thread th = new Thread (new ThreadStart (Run));
1262 public IPAddress IPAddress {
1263 get { return ((IPEndPoint) sock.LocalEndPoint).Address; }
1267 get { return ((IPEndPoint) sock.LocalEndPoint).Port; }
1270 public Exception Error {
1271 get { return error; }
1274 protected abstract void Run ();
1278 class SslHttpServer : HttpServer {
1279 X509Certificate _certificate;
1281 protected override void Run ()
1284 Socket client = sock.Accept ();
1285 NetworkStream ns = new NetworkStream (client, true);
1286 SslServerStream s = new SslServerStream (ns, Certificate, false, false);
1287 s.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback (GetPrivateKey);
1289 StreamReader reader = new StreamReader (s);
1290 StreamWriter writer = new StreamWriter (s, Encoding.ASCII);
1293 string hello = "<html><body><h1>Hello World!</h1></body></html>";
1294 string answer = "HTTP/1.0 200\r\n" +
1295 "Connection: close\r\n" +
1296 "Content-Type: text/html\r\n" +
1297 "Content-Encoding: " + Encoding.ASCII.WebName + "\r\n" +
1298 "Content-Length: " + hello.Length + "\r\n" +
1303 line = reader.ReadLine ();
1304 } while (line != "" && line != null && line.Length > 0);
1306 // Now the content. We know it's 100 bytes.
1307 // This makes BeginRead in sslclientstream block.
1308 char [] cs = new char [100];
1309 reader.Read (cs, 0, 100);
1311 writer.Write (answer);
1313 evt.WaitOne (50000, false);
1314 } catch (Exception e) {
1319 X509Certificate Certificate {
1321 if (_certificate == null)
1322 _certificate = new X509Certificate (CertData.Certificate);
1324 return _certificate;
1328 AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
1330 PrivateKey key = new PrivateKey (CertData.PrivateKey, null);
1336 public readonly static byte [] Certificate = {
1337 48, 130, 1, 191, 48, 130, 1, 40, 160, 3, 2, 1, 2, 2, 16, 36,
1338 14, 97, 190, 146, 132, 208, 71, 175, 6, 87, 168, 185, 175, 55, 43, 48,
1339 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 18,
1340 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 111, 110, 122, 97,
1341 108, 111, 48, 30, 23, 13, 48, 53, 48, 54, 50, 50, 49, 57, 51, 48,
1342 52, 54, 90, 23, 13, 51, 57, 49, 50, 51, 49, 50, 51, 53, 57, 53,
1343 57, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103,
1344 111, 110, 122, 97, 108, 111, 48, 129, 158, 48, 13, 6, 9, 42, 134, 72,
1345 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 140, 0, 48, 129, 136, 2,
1346 129, 129, 0, 138, 9, 38, 25, 166, 252, 59, 26, 39, 184, 128, 216, 38,
1347 73, 41, 86, 30, 228, 160, 205, 41, 135, 115, 223, 44, 62, 42, 198, 178,
1348 190, 81, 11, 25, 21, 216, 49, 179, 130, 246, 52, 97, 175, 212, 94, 157,
1349 231, 162, 66, 161, 103, 63, 204, 83, 141, 172, 119, 97, 225, 206, 98, 101,
1350 210, 106, 2, 206, 81, 90, 173, 47, 41, 199, 209, 241, 177, 177, 96, 207,
1351 254, 220, 190, 66, 180, 153, 0, 209, 14, 178, 69, 194, 3, 37, 116, 239,
1352 49, 23, 185, 245, 255, 126, 35, 85, 246, 56, 244, 107, 117, 24, 14, 57,
1353 9, 111, 147, 189, 220, 142, 57, 104, 153, 193, 205, 19, 14, 22, 157, 16,
1354 24, 80, 201, 2, 2, 0, 17, 163, 23, 48, 21, 48, 19, 6, 3, 85,
1355 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1,
1356 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3,
1357 129, 129, 0, 64, 49, 57, 253, 218, 198, 229, 51, 189, 12, 154, 225, 183,
1358 160, 147, 90, 113, 172, 69, 122, 28, 77, 97, 215, 231, 194, 150, 29, 196,
1359 65, 95, 218, 99, 142, 111, 79, 205, 109, 76, 32, 92, 220, 76, 88, 53,
1360 237, 80, 11, 85, 44, 91, 21, 210, 12, 34, 223, 234, 18, 187, 136, 62,
1361 26, 240, 103, 180, 12, 226, 221, 250, 247, 129, 51, 23, 129, 165, 56, 67,
1362 43, 83, 244, 110, 207, 24, 253, 195, 16, 46, 80, 113, 80, 18, 2, 254,
1363 120, 147, 151, 164, 23, 210, 230, 100, 19, 197, 179, 28, 194, 48, 106, 159,
1364 155, 144, 37, 82, 44, 160, 40, 52, 146, 174, 77, 188, 160, 230, 75, 172,
1368 public readonly static byte [] PrivateKey = {
1369 30, 241, 181, 176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
1370 0, 0, 0, 0, 84, 2, 0, 0, 7, 2, 0, 0, 0, 36, 0, 0,
1371 82, 83, 65, 50, 0, 4, 0, 0, 17, 0, 0, 0, 201, 80, 24, 16,
1372 157, 22, 14, 19, 205, 193, 153, 104, 57, 142, 220, 189, 147, 111, 9, 57,
1373 14, 24, 117, 107, 244, 56, 246, 85, 35, 126, 255, 245, 185, 23, 49, 239,
1374 116, 37, 3, 194, 69, 178, 14, 209, 0, 153, 180, 66, 190, 220, 254, 207,
1375 96, 177, 177, 241, 209, 199, 41, 47, 173, 90, 81, 206, 2, 106, 210, 101,
1376 98, 206, 225, 97, 119, 172, 141, 83, 204, 63, 103, 161, 66, 162, 231, 157,
1377 94, 212, 175, 97, 52, 246, 130, 179, 49, 216, 21, 25, 11, 81, 190, 178,
1378 198, 42, 62, 44, 223, 115, 135, 41, 205, 160, 228, 30, 86, 41, 73, 38,
1379 216, 128, 184, 39, 26, 59, 252, 166, 25, 38, 9, 138, 175, 88, 190, 223,
1380 27, 24, 224, 123, 190, 69, 164, 234, 129, 59, 108, 229, 248, 62, 187, 15,
1381 235, 147, 162, 83, 47, 123, 170, 190, 224, 31, 215, 110, 143, 31, 227, 216,
1382 85, 88, 154, 83, 207, 229, 41, 28, 237, 116, 181, 17, 37, 141, 224, 185,
1383 164, 144, 141, 233, 164, 138, 177, 241, 115, 181, 230, 150, 7, 92, 139, 141,
1384 113, 95, 57, 191, 211, 165, 217, 250, 197, 68, 164, 184, 168, 43, 48, 65,
1385 177, 237, 173, 144, 148, 221, 62, 189, 147, 63, 216, 188, 206, 103, 226, 171,
1386 32, 20, 230, 116, 144, 192, 1, 39, 202, 87, 74, 250, 6, 142, 188, 23,
1387 45, 4, 112, 191, 253, 67, 69, 70, 128, 143, 44, 234, 41, 96, 195, 82,
1388 202, 35, 158, 149, 240, 151, 23, 25, 166, 179, 85, 144, 58, 120, 149, 229,
1389 205, 34, 8, 110, 86, 119, 130, 210, 37, 173, 65, 71, 169, 67, 8, 51,
1390 20, 96, 51, 155, 3, 39, 85, 187, 40, 193, 57, 19, 99, 78, 173, 28,
1391 129, 154, 108, 175, 8, 138, 237, 71, 27, 148, 129, 35, 47, 57, 101, 237,
1392 168, 178, 227, 221, 212, 63, 124, 254, 253, 215, 183, 159, 49, 103, 74, 49,
1393 67, 160, 171, 72, 194, 215, 108, 251, 178, 18, 184, 100, 211, 105, 21, 186,
1394 39, 66, 218, 154, 72, 222, 90, 237, 179, 251, 51, 224, 212, 56, 251, 6,
1395 209, 151, 198, 176, 89, 110, 35, 141, 248, 237, 223, 68, 135, 206, 207, 169,
1396 254, 219, 243, 130, 71, 11, 94, 113, 233, 92, 63, 156, 169, 72, 215, 110,
1397 95, 94, 191, 50, 59, 89, 187, 59, 183, 99, 161, 146, 233, 245, 219, 80,
1398 87, 113, 251, 50, 144, 195, 158, 46, 189, 232, 119, 91, 75, 22, 6, 176,
1399 39, 206, 25, 196, 213, 195, 219, 24, 28, 103, 104, 36, 137, 128, 4, 119,
1400 163, 40, 126, 87, 18, 86, 128, 243, 213, 101, 2, 237, 78, 64, 160, 55,
1401 199, 93, 90, 126, 175, 199, 55, 89, 234, 190, 5, 16, 196, 88, 28, 208,
1402 28, 92, 32, 115, 204, 9, 202, 101, 15, 123, 43, 75, 90, 144, 95, 179,
1403 102, 249, 57, 150, 204, 99, 147, 203, 16, 63, 81, 244, 226, 237, 82, 204,
1404 20, 200, 140, 65, 83, 217, 161, 23, 123, 37, 115, 12, 100, 73, 70, 190,
1405 32, 235, 174, 140, 148, 157, 47, 238, 40, 208, 228, 80, 54, 187, 156, 252,
1406 253, 230, 231, 156, 138, 125, 96, 79, 3, 27, 143, 55, 146, 169, 165, 61,
1407 238, 60, 227, 77, 217, 93, 117, 122, 111, 46, 173, 113,