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
36 private Random rand = new Random();
37 private byte[] data64KB = new byte[64 * 1024];
42 ServicePointManager.Expect100Continue = false;
43 rand.NextBytes(data64KB);
49 [Ignore ("Ignore failures in Sys.Net")]
51 public void Proxy_Null ()
53 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
54 Assert.IsNotNull (req.Proxy, "#1");
57 Assert.IsNull (req.Proxy, "#2");
62 } catch (ArgumentNullException ex) {
63 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#3");
64 Assert.IsNull (ex.InnerException, "#4");
65 Assert.IsNotNull (ex.Message, "#5");
66 Assert.IsNotNull (ex.ParamName, "#6");
67 Assert.AreEqual ("value", ex.ParamName, "#7");
73 [Category("InetAccess")]
75 [Ignore ("NMA - wrong cookies number returned")]
79 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
80 Assert.IsNotNull (req.IfModifiedSince, "req:If Modified Since: ");
82 req.UserAgent = "MonoClient v1.0";
83 Assert.AreEqual ("User-Agent", req.Headers.GetKey (0), "#A1");
84 Assert.AreEqual ("MonoClient v1.0", req.Headers.Get (0), "#A2");
86 HttpWebResponse res = (HttpWebResponse) req.GetResponse ();
87 Assert.AreEqual ("OK", res.StatusCode.ToString (), "#B1");
88 Assert.AreEqual ("OK", res.StatusDescription, "#B2");
90 Assert.AreEqual ("text/html; charset=ISO-8859-1", res.Headers.Get ("Content-Type"), "#C1");
91 Assert.IsNotNull (res.LastModified, "#C2");
92 Assert.AreEqual (0, res.Cookies.Count, "#C3");
98 public void AddRange ()
100 HttpWebRequest req = (HttpWebRequest) WebRequest.Create ("http://www.google.com");
102 req.AddRange (50, 90);
103 req.AddRange ("bytes", 100);
104 req.AddRange ("bytes", 100, 120);
105 Assert.AreEqual ("bytes=10-,50-90,100-,100-120", req.Headers ["Range"], "#1");
107 req.AddRange ("bits", 2000);
109 } catch (InvalidOperationException) {}
112 [Test] // bug #471782
113 public void CloseRequestStreamAfterReadingResponse ()
115 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
116 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
118 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
121 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
124 req.ReadWriteTimeout = 2000;
126 byte [] data = new byte [128];
127 req.ContentLength = data.Length;
129 Stream rs = req.GetRequestStream ();
130 rs.Write (data, 0, data.Length);
133 HttpWebResponse response = (HttpWebResponse) req.GetResponse ();
143 [Category("InetAccess")]
144 public void Cookies1 ()
146 // The purpose of this test is to ensure that the cookies we get from a request
147 // are stored in both, the CookieCollection in HttpWebResponse and the CookieContainer
148 // in HttpWebRequest.
149 // If this URL stops sending *one* and only one cookie, replace it.
150 string url = "http://www.elmundo.es";
151 CookieContainer cookies = new CookieContainer ();
152 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
153 req.KeepAlive = false;
154 req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv; 1.7.6) Gecko/20050317 Firefox/1.0.2";
155 req.CookieContainer = cookies;
156 Assert.AreEqual (0, cookies.Count, "#01");
157 using (HttpWebResponse res = (HttpWebResponse) req.GetResponse()) {
158 CookieCollection coll = req.CookieContainer.GetCookies (new Uri (url));
159 Assert.AreEqual (1, coll.Count, "#02");
160 Assert.AreEqual (1, res.Cookies.Count, "#03");
161 Cookie one = coll [0];
162 Cookie two = res.Cookies [0];
163 Assert.AreEqual (true, object.ReferenceEquals (one, two), "#04");
167 #if !TARGET_JVM //NotWorking
169 public void SslClientBlock ()
171 // This tests that the write request/initread/write body sequence does not hang
173 // If there's a regression for this, the test will hang.
174 ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
176 SslHttpServer server = new SslHttpServer ();
179 string url = String.Format ("https://{0}:{1}/nothing.html", server.IPAddress, server.Port);
180 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
181 request.Method = "POST";
182 Stream stream = request.GetRequestStream ();
183 byte [] bytes = new byte [100];
184 stream.Write (bytes, 0, bytes.Length);
186 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
187 Assert.AreEqual (200, (int) resp.StatusCode, "StatusCode");
188 StreamReader sr = new StreamReader (resp.GetResponseStream (), Encoding.UTF8);
189 string x = sr.ReadToEnd ();
193 if (server.Error != null)
196 ServicePointManager.CertificatePolicy = null;
202 [Category("NotWorking")]
204 public void Missing_ContentEncoding ()
206 ServicePointManager.CertificatePolicy = new AcceptAllPolicy ();
208 BadChunkedServer server = new BadChunkedServer ();
211 string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
212 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
213 request.Method = "GET";
214 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
215 Assert.AreEqual ("", resp.ContentEncoding);
218 if (server.Error != null)
221 ServicePointManager.CertificatePolicy = null;
227 [Category ("NotWorking")]
229 public void BadServer_ChunkedClose ()
231 // The server will send a chunked response without a 'last-chunked' mark
232 // and then shutdown the socket for sending.
233 BadChunkedServer server = new BadChunkedServer ();
235 string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
236 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
237 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
240 byte [] bytes = new byte [32];
241 // Using StreamReader+UTF8Encoding here fails on MS runtime
242 Stream stream = resp.GetResponseStream ();
243 int nread = stream.Read (bytes, 0, 32);
244 Assert.AreEqual (16, nread, "#01");
245 x = Encoding.ASCII.GetString (bytes, 0, 16);
251 if (server.Error != null)
254 Assert.AreEqual ("1234567890123456", x);
258 [Ignore ("This test asserts that our code violates RFC 2616")]
259 public void MethodCase ()
261 ListDictionary methods = new ListDictionary ();
263 methods.Add ("post", "POST");
264 methods.Add ("puT", "PUT");
266 methods.Add ("post", "post");
267 methods.Add ("puT", "puT");
269 methods.Add ("POST", "POST");
270 methods.Add ("whatever", "whatever");
271 methods.Add ("PUT", "PUT");
273 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
274 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
276 foreach (DictionaryEntry de in methods) {
277 SocketResponder responder = new SocketResponder (new IPEndPoint (IPAddress.Loopback, 8000),
278 new SocketRequestHandler (EchoRequestHandler));
281 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
282 req.Method = (string) de.Key;
284 req.ReadWriteTimeout = 2000;
285 req.KeepAlive = false;
286 Stream rs = req.GetRequestStream ();
288 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
289 StreamReader sr = new StreamReader (resp.GetResponseStream (),
291 string line = sr.ReadLine ();
293 Assert.AreEqual (((string) de.Value) + " /test/ HTTP/1.1",
302 public void BeginGetRequestStream_Body_NotAllowed ()
304 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
305 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
307 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
310 HttpWebRequest request;
312 request = (HttpWebRequest) WebRequest.Create (url);
313 request.Method = "GET";
316 request.BeginGetRequestStream (null, null);
318 } catch (ProtocolViolationException ex) {
319 // Cannot send a content-body with this
321 Assert.IsNull (ex.InnerException, "#A2");
322 Assert.IsNotNull (ex.Message, "#A3");
325 request = (HttpWebRequest) WebRequest.Create (url);
326 request.Method = "HEAD";
329 request.BeginGetRequestStream (null, null);
331 } catch (ProtocolViolationException ex) {
332 // Cannot send a content-body with this
334 Assert.IsNull (ex.InnerException, "#B2");
335 Assert.IsNotNull (ex.Message, "#B3");
340 [Test] // bug #465613
341 public void BeginGetRequestStream_NoBuffering ()
343 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8002);
344 string url = "http://" + IPAddress.Loopback.ToString () + ":8002/test/";
346 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
353 req = (HttpWebRequest) WebRequest.Create (url);
355 req.SendChunked = false;
356 req.KeepAlive = false;
357 req.AllowWriteStreamBuffering = false;
359 ar = req.BeginGetRequestStream (null, null);
360 rs = req.EndGetRequestStream (ar);
363 req = (HttpWebRequest) WebRequest.Create (url);
365 req.SendChunked = false;
366 req.KeepAlive = true;
367 req.AllowWriteStreamBuffering = false;
370 req.BeginGetRequestStream (null, null);
372 } catch (ProtocolViolationException ex) {
373 // When performing a write operation with
374 // AllowWriteStreamBuffering set to false,
375 // you must either set ContentLength to a
376 // non-negative number or set SendChunked
378 Assert.IsNull (ex.InnerException, "#A2");
379 Assert.IsNotNull (ex.Message, "#A3");
382 req = (HttpWebRequest) WebRequest.Create (url);
384 req.SendChunked = false;
385 req.KeepAlive = true;
386 req.AllowWriteStreamBuffering = false;
387 req.ContentLength = 0;
389 ar = req.BeginGetRequestStream (null, null);
390 rs = req.EndGetRequestStream (ar);
395 [Test] // bug #508027
396 public void BeginGetResponse ()
398 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8003);
399 string url = "http://" + IPAddress.Loopback.ToString () + ":8003/test/";
401 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
406 req = (HttpWebRequest) WebRequest.Create (url);
408 req.SendChunked = false;
409 req.KeepAlive = false;
410 req.AllowWriteStreamBuffering = false;
411 req.BeginGetResponse (null, null);
414 req = (HttpWebRequest) WebRequest.Create (url);
416 req.SendChunked = true;
417 req.KeepAlive = false;
418 req.AllowWriteStreamBuffering = false;
419 req.BeginGetResponse (null, null);
422 req = (HttpWebRequest) WebRequest.Create (url);
424 req.ContentLength = 5;
425 req.SendChunked = false;
426 req.KeepAlive = false;
427 req.AllowWriteStreamBuffering = false;
428 req.BeginGetResponse (null, null);
431 req = (HttpWebRequest) WebRequest.Create (url);
433 req.SendChunked = false;
434 req.KeepAlive = true;
435 req.AllowWriteStreamBuffering = false;
437 req.BeginGetResponse (null, null);
441 req.BeginGetResponse (null, null);
442 } catch (ProtocolViolationException ex) {
443 // Either ContentLength must be set to a non-negative
444 // number, or SendChunked set to true in order to perform
445 // the write operation when AllowWriteStreamBuffering
447 Assert.IsNull (ex.InnerException, "#A2");
448 Assert.IsNotNull (ex.Message, "#A3");
454 req = (HttpWebRequest) WebRequest.Create (url);
456 req.SendChunked = false;
457 req.KeepAlive = false;
458 req.AllowWriteStreamBuffering = false;
459 req.ContentLength = 5;
460 req.BeginGetResponse (null, null);
463 req = (HttpWebRequest) WebRequest.Create (url);
465 req.SendChunked = false;
466 req.KeepAlive = true;
467 req.AllowWriteStreamBuffering = false;
468 req.ContentLength = 5;
469 req.BeginGetResponse (null, null);
472 req = (HttpWebRequest) WebRequest.Create (url);
474 req.SendChunked = true;
476 req.BeginGetResponse (null, null);
480 req.BeginGetResponse (null, null);
482 } catch (ProtocolViolationException ex) {
483 // Content-Length cannot be set for a
484 // non-write operation
485 Assert.IsNull (ex.InnerException, "#B2");
486 Assert.IsNotNull (ex.Message, "#B3");
492 req = (HttpWebRequest) WebRequest.Create (url);
494 req.ContentLength = 5;
496 req.BeginGetResponse (null, null);
500 req.BeginGetResponse (null, null);
502 } catch (ProtocolViolationException ex) {
503 // Content-Length cannot be set for a
504 // non-write operation
505 Assert.IsNull (ex.InnerException, "#C2");
506 Assert.IsNotNull (ex.Message, "#C3");
512 req = (HttpWebRequest) WebRequest.Create (url);
514 req.ContentLength = 0;
516 req.BeginGetResponse (null, null);
520 req.BeginGetResponse (null, null);
522 } catch (ProtocolViolationException ex) {
523 // Content-Length cannot be set for a
524 // non-write operation
525 Assert.IsNull (ex.InnerException, "#D2");
526 Assert.IsNotNull (ex.Message, "#D3");
534 [Test] // bug #429200
535 public void GetRequestStream ()
537 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
538 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
540 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
543 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
546 req.ReadWriteTimeout = 2000;
548 Stream rs1 = req.GetRequestStream ();
549 Stream rs2 = req.GetRequestStream ();
551 Assert.IsNotNull (rs1, "#1");
552 Assert.AreSame (rs1, rs2, "#2");
558 [Test] // bug #510661 and #514996
559 [Category ("NotWorking")]
560 public void GetRequestStream_Close_NotAllBytesWritten ()
562 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
563 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
565 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
571 req = (HttpWebRequest) WebRequest.Create (url);
573 req.ContentLength = 2;
574 rs = req.GetRequestStream ();
578 } catch (WebException ex) {
579 // The request was aborted: The request was canceled
580 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
581 Assert.IsNotNull (ex.Message, "#A3");
582 Assert.IsNull (ex.Response, "#A4");
583 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#A5");
585 // Cannot close stream until all bytes are written
586 Exception inner = ex.InnerException;
587 Assert.IsNotNull (inner, "#A6");
588 Assert.AreEqual (typeof (IOException), inner.GetType (), "#A7");
589 Assert.IsNull (inner.InnerException, "#A8");
590 Assert.IsNotNull (inner.Message, "#A9");
593 req = (HttpWebRequest) WebRequest.Create (url);
595 req.ContentLength = 2;
596 rs = req.GetRequestStream ();
601 } catch (WebException ex) {
602 // The request was aborted: The request was canceled
603 Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
604 Assert.IsNotNull (ex.Message, "#B3");
605 Assert.IsNull (ex.Response, "#B4");
606 Assert.AreEqual (WebExceptionStatus.RequestCanceled, ex.Status, "#B5");
608 // Cannot close stream until all bytes are written
609 Exception inner = ex.InnerException;
610 Assert.IsNotNull (inner, "#B6");
611 Assert.AreEqual (typeof (IOException), inner.GetType (), "#B7");
612 Assert.IsNull (inner.InnerException, "#B8");
613 Assert.IsNotNull (inner.Message, "#B9");
616 req = (HttpWebRequest) WebRequest.Create (url);
618 req.ContentLength = 2;
619 rs = req.GetRequestStream ();
626 [Test] // bug #510642
627 public void GetRequestStream_Write_Overflow ()
629 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8001);
630 string url = "http://" + IPAddress.Loopback.ToString () + ":8001/test/";
632 // buffered, non-chunked
633 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
640 req = (HttpWebRequest) WebRequest.Create (url);
641 req.ProtocolVersion = HttpVersion.Version11;
644 req.ReadWriteTimeout = 2000;
645 req.ContentLength = 2;
647 rs = req.GetRequestStream ();
650 buffer = new byte [] { 0x2a, 0x1d };
652 rs.Write (buffer, 0, buffer.Length);
654 } catch (ProtocolViolationException ex) {
655 // Bytes to be written to the stream exceed
656 // Content-Length bytes size specified
657 Assert.IsNull (ex.InnerException, "#A2");
658 Assert.IsNotNull (ex.Message, "#A3");
663 req = (HttpWebRequest) WebRequest.Create (url);
664 req.ProtocolVersion = HttpVersion.Version11;
667 req.ReadWriteTimeout = 2000;
668 req.ContentLength = 2;
670 rs = req.GetRequestStream ();
672 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
674 rs.Write (buffer, 0, buffer.Length);
676 } catch (ProtocolViolationException ex) {
677 // Bytes to be written to the stream exceed
678 // Content-Length bytes size specified
679 Assert.IsNull (ex.InnerException, "#B2");
680 Assert.IsNotNull (ex.Message, "#B3");
687 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
695 req = (HttpWebRequest) WebRequest.Create (url);
696 req.ProtocolVersion = HttpVersion.Version11;
698 req.SendChunked = true;
700 req.ReadWriteTimeout = 2000;
701 req.ContentLength = 2;
703 rs = req.GetRequestStream ();
706 buffer = new byte [] { 0x2a, 0x1d };
707 rs.Write (buffer, 0, buffer.Length);
711 req = (HttpWebRequest) WebRequest.Create (url);
712 req.ProtocolVersion = HttpVersion.Version11;
714 req.SendChunked = true;
716 req.ReadWriteTimeout = 2000;
717 req.ContentLength = 2;
719 rs = req.GetRequestStream ();
721 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
722 rs.Write (buffer, 0, buffer.Length);
726 // non-buffered, non-chunked
727 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
734 req = (HttpWebRequest) WebRequest.Create (url);
735 req.AllowWriteStreamBuffering = false;
736 req.ProtocolVersion = HttpVersion.Version11;
739 req.ReadWriteTimeout = 2000;
740 req.ContentLength = 2;
742 rs = req.GetRequestStream ();
745 buffer = new byte [] { 0x2a, 0x1d };
747 rs.Write (buffer, 0, buffer.Length);
749 } catch (ProtocolViolationException ex) {
750 // Bytes to be written to the stream exceed
751 // Content-Length bytes size specified
752 Assert.IsNull (ex.InnerException, "#C2");
753 Assert.IsNotNull (ex.Message, "#3");
758 req = (HttpWebRequest) WebRequest.Create (url);
759 req.AllowWriteStreamBuffering = false;
760 req.ProtocolVersion = HttpVersion.Version11;
763 req.ReadWriteTimeout = 2000;
764 req.ContentLength = 2;
766 rs = req.GetRequestStream ();
768 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
770 rs.Write (buffer, 0, buffer.Length);
772 } catch (ProtocolViolationException ex) {
773 // Bytes to be written to the stream exceed
774 // Content-Length bytes size specified
775 Assert.IsNull (ex.InnerException, "#D2");
776 Assert.IsNotNull (ex.Message, "#D3");
782 // non-buffered, chunked
783 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (EchoRequestHandler))) {
790 req = (HttpWebRequest) WebRequest.Create (url);
791 req.AllowWriteStreamBuffering = false;
792 req.ProtocolVersion = HttpVersion.Version11;
794 req.SendChunked = true;
796 req.ReadWriteTimeout = 2000;
797 req.ContentLength = 2;
799 rs = req.GetRequestStream ();
802 buffer = new byte [] { 0x2a, 0x1d };
803 rs.Write (buffer, 0, buffer.Length);
806 req = (HttpWebRequest) WebRequest.Create (url);
807 req.AllowWriteStreamBuffering = false;
808 req.ProtocolVersion = HttpVersion.Version11;
810 req.SendChunked = true;
812 req.ReadWriteTimeout = 2000;
813 req.ContentLength = 2;
815 rs = req.GetRequestStream ();
817 buffer = new byte [] { 0x2a, 0x2c, 0x1d };
818 rs.Write (buffer, 0, buffer.Length);
824 [Ignore ("This test asserts that our code violates RFC 2616")]
825 public void GetRequestStream_Body_NotAllowed ()
827 string [] methods = new string [] { "GET", "HEAD", "CONNECT",
828 "get", "HeAd", "ConNect" };
830 foreach (string method in methods) {
831 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (
832 "http://localhost:8000");
835 req.GetRequestStream ();
836 Assert.Fail ("#1:" + method);
837 } catch (ProtocolViolationException ex) {
838 Assert.AreEqual (typeof (ProtocolViolationException), ex.GetType (), "#2:" + method);
839 Assert.IsNull (ex.InnerException, "#3:" + method);
840 Assert.IsNotNull (ex.Message, "#4:" + method);
847 [Category("NotWorking")]
849 [Ignore ("This does not timeout any more. That's how MS works when reading small responses")]
850 public void ReadTimeout ()
852 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
853 string url = "http://" + localEP.ToString () + "/original/";
855 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
858 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
860 req.AllowAutoRedirect = false;
862 req.ReadWriteTimeout = 2000;
863 req.KeepAlive = false;
864 Stream rs = req.GetRequestStream ();
866 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
868 Stream s = resp.GetResponseStream ();
871 } catch (WebException ex) {
872 Assert.AreEqual (typeof (WebException), ex.GetType (), "#2");
873 Assert.IsNull (ex.InnerException, "#3");
874 Assert.IsNull (ex.Response, "#4");
875 Assert.AreEqual (WebExceptionStatus.Timeout, ex.Status, "#5");
882 [Test] // bug #324300
884 [Category("NotWorking")]
886 public void AllowAutoRedirect ()
888 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
889 string url = "http://" + localEP.ToString () + "/original/";
891 // allow autoredirect
892 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
895 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
898 req.ReadWriteTimeout = 2000;
899 req.KeepAlive = false;
900 Stream rs = req.GetRequestStream ();
902 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
903 StreamReader sr = new StreamReader (resp.GetResponseStream (),
905 string body = sr.ReadToEnd ();
907 Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#A1");
908 Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
909 localEP.ToString () + "/moved/", "#A2");
910 Assert.AreEqual ("GET", resp.Method, "#A3");
911 Assert.AreEqual ("LOOKS OK", body, "#A4");
916 // do not allow autoredirect
917 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
920 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
922 req.AllowAutoRedirect = false;
924 req.ReadWriteTimeout = 1000;
925 req.KeepAlive = false;
926 Stream rs = req.GetRequestStream ();
928 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
929 Assert.AreEqual (resp.StatusCode, HttpStatusCode.Found, "#B1");
930 Assert.AreEqual (url, resp.ResponseUri.ToString (), "#B2");
931 Assert.AreEqual ("POST", resp.Method, "#B3");
937 [Test] // bug #324347
938 [Category ("NotWorking")]
939 public void InternalServerError ()
941 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
942 string url = "http://" + localEP.ToString () + "/original/";
945 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
948 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
951 req.ReadWriteTimeout = 2000;
952 req.KeepAlive = false;
953 Stream rs = req.GetRequestStream ();
959 } catch (WebException ex) {
960 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
961 Assert.IsNull (ex.InnerException, "#A3");
962 Assert.IsNotNull (ex.Message, "#A4");
963 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A5");
965 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
966 Assert.IsNotNull (webResponse, "#A6");
967 Assert.AreEqual ("POST", webResponse.Method, "#A7");
968 webResponse.Close ();
975 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (InternalErrorHandler))) {
978 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
981 req.ReadWriteTimeout = 2000;
982 req.KeepAlive = false;
987 } catch (WebException ex) {
988 Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
989 Assert.IsNull (ex.InnerException, "#B3");
990 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
992 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
993 Assert.IsNotNull (webResponse, "#B5");
994 Assert.AreEqual ("GET", webResponse.Method, "#B6");
995 webResponse.Close ();
1003 [Category ("NotWorking")] // #B3 fails; we get a SocketException: An existing connection was forcibly closed by the remote host
1004 public void NoContentLength ()
1006 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
1007 string url = "http://" + localEP.ToString () + "/original/";
1010 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
1013 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1014 req.Method = "POST";
1016 req.ReadWriteTimeout = 2000;
1017 req.KeepAlive = false;
1018 Stream rs = req.GetRequestStream ();
1023 Assert.Fail ("#A1");
1024 } catch (WebException ex) {
1026 // The underlying connection was closed:
1027 // An unexpected error occurred on a
1029 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
1030 Assert.IsNotNull (ex.InnerException, "#A3");
1031 Assert.AreEqual (WebExceptionStatus.ReceiveFailure, ex.Status, "#A4");
1032 Assert.AreEqual (typeof (IOException), ex.InnerException.GetType (), "#A5");
1034 // Unable to read data from the transport connection:
1035 // A connection attempt failed because the connected party
1036 // did not properly respond after a period of time, or
1037 // established connection failed because connected host has
1038 // failed to respond
1039 IOException ioe = (IOException) ex.InnerException;
1040 Assert.IsNotNull (ioe.InnerException, "#A6");
1041 Assert.IsNotNull (ioe.Message, "#A7");
1042 Assert.AreEqual (typeof (SocketException), ioe.InnerException.GetType (), "#A8");
1044 // An existing connection was forcibly
1045 // closed by the remote host
1046 SocketException soe = (SocketException) ioe.InnerException;
1047 Assert.IsNull (soe.InnerException, "#A9");
1048 Assert.IsNotNull (soe.Message, "#A10");
1050 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1051 Assert.IsNull (webResponse, "#A11");
1053 // The remote server returned an error:
1054 // (500) Internal Server Error
1055 Assert.AreEqual (typeof (WebException), ex.GetType (), "#A2");
1056 Assert.IsNull (ex.InnerException, "#A3");
1057 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#A4");
1059 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1060 Assert.IsNotNull (webResponse, "#A5");
1061 Assert.AreEqual ("POST", webResponse.Method, "#A6");
1062 webResponse.Close ();
1070 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (NoContentLengthHandler))) {
1073 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1076 req.ReadWriteTimeout = 2000;
1077 req.KeepAlive = false;
1081 Assert.Fail ("#B1");
1082 } catch (WebException ex) {
1083 // The remote server returned an error:
1084 // (500) Internal Server Error
1085 Assert.AreEqual (typeof (WebException), ex.GetType (), "#B2");
1086 Assert.IsNull (ex.InnerException, "#B3");
1087 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#B4");
1089 HttpWebResponse webResponse = ex.Response as HttpWebResponse;
1090 Assert.IsNotNull (webResponse, "#B5");
1091 Assert.AreEqual ("GET", webResponse.Method, "#B6");
1092 webResponse.Close ();
1099 [Test] // bug #513087
1100 public void NonStandardVerb ()
1102 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
1103 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/moved/";
1105 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (VerbEchoHandler))) {
1108 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1109 req.Method = "WhatEver";
1110 req.KeepAlive = false;
1111 req.Timeout = 20000;
1112 req.ReadWriteTimeout = 20000;
1114 Stream rs = req.GetRequestStream ();
1117 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1118 StreamReader sr = new StreamReader (resp.GetResponseStream (),
1120 string body = sr.ReadToEnd ();
1122 Assert.AreEqual (resp.StatusCode, HttpStatusCode.OK, "#1");
1123 Assert.AreEqual (resp.ResponseUri.ToString (), "http://" +
1124 ep.ToString () + "/moved/", "#2");
1125 Assert.AreEqual ("WhatEver", resp.Method, "#3");
1126 Assert.AreEqual ("WhatEver", body, "#4");
1134 [Category ("NotWorking")] // Assert #2 fails
1135 public void NotModifiedSince ()
1137 IPEndPoint ep = new IPEndPoint (IPAddress.Loopback, 8000);
1138 string url = "http://" + IPAddress.Loopback.ToString () + ":8000/test/";
1140 using (SocketResponder responder = new SocketResponder (ep, new SocketRequestHandler (NotModifiedSinceHandler))) {
1143 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1145 req.KeepAlive = false;
1146 req.Timeout = 20000;
1147 req.ReadWriteTimeout = 20000;
1149 req.Headers.Add (HttpRequestHeader.IfNoneMatch, "898bbr2347056cc2e096afc66e104653");
1151 req.Headers.Add ("If-None-Match", "898bbr2347056cc2e096afc66e104653");
1153 req.IfModifiedSince = new DateTime (2010, 01, 04);
1155 DateTime start = DateTime.Now;
1156 HttpWebResponse response = null;
1161 } catch (WebException e) {
1162 response = (HttpWebResponse) e.Response;
1165 Assert.IsNotNull (response, "#2");
1166 using (Stream stream = response.GetResponseStream ()) {
1167 byte [] buffer = new byte [4096];
1168 int bytesRead = stream.Read (buffer, 0, buffer.Length);
1169 Assert.AreEqual (0, bytesRead, "#3");
1172 TimeSpan elapsed = DateTime.Now - start;
1173 Assert.IsTrue (elapsed.TotalMilliseconds < 2000, "#4");
1180 [Test] // bug #324182
1182 [Category ("NotWorking")]
1184 public void Stream_CanTimeout ()
1186 IPEndPoint localEP = new IPEndPoint (IPAddress.Loopback, 8764);
1187 string url = "http://" + localEP.ToString () + "/original/";
1189 // allow autoredirect
1190 using (SocketResponder responder = new SocketResponder (localEP, new SocketRequestHandler (RedirectRequestHandler))) {
1193 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (url);
1194 req.Method = "POST";
1196 req.ReadWriteTimeout = 2000;
1197 req.KeepAlive = false;
1198 Stream rs = req.GetRequestStream ();
1199 Assert.IsTrue (rs.CanTimeout, "#1");
1201 using (HttpWebResponse resp = (HttpWebResponse) req.GetResponse ()) {
1202 Stream os = resp.GetResponseStream ();
1203 Assert.IsTrue (os.CanTimeout, "#2");
1211 [Test] // bug #353495
1212 [Category ("NotWorking")]
1213 public void LastModifiedKind ()
1215 const string reqURL = "http://coffeefaq.com/site/node/25";
1216 HttpWebRequest req = (HttpWebRequest) WebRequest.Create (reqURL);
1217 HttpWebResponse resp = (HttpWebResponse) req.GetResponse ();
1218 DateTime lastMod = resp.LastModified;
1219 string rawLastMod = resp.Headers ["Last-Modified"];
1221 //Assert.AreEqual ("Tue, 15 Jan 2008 08:59:59 GMT", rawLastMod, "#1");
1223 Assert.AreEqual (DateTimeKind.Local, lastMod.Kind, "#2");
1225 req = (HttpWebRequest) WebRequest.Create (reqURL);
1226 req.IfModifiedSince = lastMod;
1228 resp = (HttpWebResponse) req.GetResponse ();
1230 Assert.Fail ("Should result in 304");
1231 } catch (WebException ex) {
1232 Assert.AreEqual (WebExceptionStatus.ProtocolError, ex.Status, "#3");
1233 Assert.AreEqual (((HttpWebResponse) ex.Response).StatusCode, HttpStatusCode.NotModified, "#4");
1237 static byte [] EchoRequestHandler (Socket socket)
1239 MemoryStream ms = new MemoryStream ();
1240 byte [] buffer = new byte [4096];
1241 int bytesReceived = socket.Receive (buffer);
1242 while (bytesReceived > 0) {
1243 ms.Write (buffer, 0, bytesReceived);
1244 // We don't check for Content-Length or anything else here, so we give the client a little time to write
1245 // after sending the headers
1247 if (socket.Available > 0) {
1248 bytesReceived = socket.Receive (buffer);
1255 StreamReader sr = new StreamReader (ms, Encoding.UTF8);
1256 string request = sr.ReadToEnd ();
1258 StringWriter sw = new StringWriter ();
1259 sw.WriteLine ("HTTP/1.1 200 OK");
1260 sw.WriteLine ("Content-Type: text/xml");
1261 sw.WriteLine ("Content-Length: " + request.Length.ToString (CultureInfo.InvariantCulture));
1266 return Encoding.UTF8.GetBytes (sw.ToString ());
1269 static byte [] RedirectRequestHandler (Socket socket)
1271 MemoryStream ms = new MemoryStream ();
1272 byte [] buffer = new byte [4096];
1273 int bytesReceived = socket.Receive (buffer);
1274 while (bytesReceived > 0) {
1275 ms.Write (buffer, 0, bytesReceived);
1276 // We don't check for Content-Length or anything else here, so we give the client a little time to write
1277 // after sending the headers
1279 if (socket.Available > 0) {
1280 bytesReceived = socket.Receive (buffer);
1287 string statusLine = null;
1288 using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1289 statusLine = sr.ReadLine ();
1292 StringWriter sw = new StringWriter ();
1293 if (statusLine.StartsWith ("POST /original/")) {
1294 sw.WriteLine ("HTTP/1.0 302 Found");
1295 sw.WriteLine ("Location: " + "http://" + IPAddress.Loopback.ToString () + ":8764/moved/");
1298 } else if (statusLine.StartsWith ("GET /moved/")) {
1299 sw.WriteLine ("HTTP/1.0 200 OK");
1300 sw.WriteLine ("Content-Type: text/plain");
1301 sw.WriteLine ("Content-Length: 8");
1303 sw.Write ("LOOKS OK");
1306 sw.WriteLine ("HTTP/1.0 500 Too Lazy");
1311 return Encoding.UTF8.GetBytes (sw.ToString ());
1314 static byte [] InternalErrorHandler (Socket socket)
1316 StringWriter sw = new StringWriter ();
1317 sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1318 sw.WriteLine ("Content-Length: 0");
1322 return Encoding.UTF8.GetBytes (sw.ToString ());
1325 static byte [] NoContentLengthHandler (Socket socket)
1327 StringWriter sw = new StringWriter ();
1328 sw.WriteLine ("HTTP/1.1 500 Too Lazy");
1332 return Encoding.UTF8.GetBytes (sw.ToString ());
1335 static byte [] NotModifiedSinceHandler (Socket socket)
1337 StringWriter sw = new StringWriter ();
1338 sw.WriteLine ("HTTP/1.1 304 Not Modified");
1339 sw.WriteLine ("Date: Fri, 06 Feb 2009 12:50:26 GMT");
1340 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");
1341 sw.WriteLine ("Not-Modified-Since: Sun, 08 Feb 2009 08:49:26 GMT");
1342 sw.WriteLine ("ETag: 898bbr2347056cc2e096afc66e104653");
1343 sw.WriteLine ("Connection: close");
1347 return Encoding.UTF8.GetBytes (sw.ToString ());
1350 static byte [] VerbEchoHandler (Socket socket)
1352 MemoryStream ms = new MemoryStream ();
1353 byte [] buffer = new byte [4096];
1354 int bytesReceived = socket.Receive (buffer);
1355 while (bytesReceived > 0) {
1356 ms.Write (buffer, 0, bytesReceived);
1357 // We don't check for Content-Length or anything else here, so we give the client a little time to write
1358 // after sending the headers
1360 if (socket.Available > 0) {
1361 bytesReceived = socket.Receive (buffer);
1368 string statusLine = null;
1369 using (StreamReader sr = new StreamReader (ms, Encoding.UTF8)) {
1370 statusLine = sr.ReadLine ();
1373 string verb = "DEFAULT";
1374 if (statusLine != null) {
1375 string [] parts = statusLine.Split (' ');
1376 if (parts.Length > 0)
1380 StringWriter sw = new StringWriter ();
1381 sw.WriteLine ("HTTP/1.1 200 OK");
1382 sw.WriteLine ("Content-Type: text/plain");
1383 sw.WriteLine ("Content-Length: " + verb.Length);
1388 return Encoding.UTF8.GetBytes (sw.ToString ());
1392 public void NtlmAuthentication ()
1394 NtlmServer server = new NtlmServer ();
1397 string url = String.Format ("http://{0}:{1}/nothing.html", server.IPAddress, server.Port);
1398 HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
1399 request.Timeout = 5000;
1400 request.Credentials = new NetworkCredential ("user", "password", "domain");
1401 HttpWebResponse resp = (HttpWebResponse) request.GetResponse ();
1403 using (StreamReader reader = new StreamReader (resp.GetResponseStream ())) {
1404 res = reader.ReadToEnd ();
1408 Assert.AreEqual ("OK", res);
1411 class NtlmServer : HttpServer {
1412 public string Where = "";
1413 protected override void Run ()
1415 Where = "before accept";
1416 Socket client = sock.Accept ();
1417 NetworkStream ns = new NetworkStream (client, false);
1418 StreamReader reader = new StreamReader (ns, Encoding.ASCII);
1420 Where = "first read";
1421 while ((line = reader.ReadLine ()) != null) {
1422 if (line.Trim () == String.Empty) {
1426 Where = "first write";
1427 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1428 writer.Write ( "HTTP/1.1 401 Unauthorized\r\n" +
1429 "WWW-Authenticate: NTLM\r\n" +
1430 "Content-Length: 5\r\n\r\nWRONG");
1433 Where = "second read";
1434 while ((line = reader.ReadLine ()) != null) {
1435 if (line.Trim () == String.Empty) {
1439 Where = "second write";
1440 writer.Write ( "HTTP/1.1 401 Unauthorized\r\n" +
1441 "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAADgAAAABggAC8GDhqIONH3sAAAAAAAAAAAAAAAA4AAAABQLODgAAAA8=\r\n" +
1442 "Content-Length: 5\r\n\r\nWRONG");
1445 Where = "third read";
1446 while ((line = reader.ReadLine ()) != null) {
1447 if (line.Trim () == String.Empty) {
1451 Where = "third write";
1452 writer.Write ( "HTTP/1.1 200 OK\r\n" +
1453 "Keep-Alive: true\r\n" +
1454 "Content-Length: 2\r\n\r\nOK");
1456 Thread.Sleep (1000);
1463 class BadChunkedServer : HttpServer {
1464 protected override void Run ()
1466 Socket client = sock.Accept ();
1467 NetworkStream ns = new NetworkStream (client, true);
1468 StreamWriter writer = new StreamWriter (ns, Encoding.ASCII);
1469 writer.Write ( "HTTP/1.1 200 OK\r\n" +
1470 "Transfer-Encoding: chunked\r\n" +
1471 "Connection: close\r\n" +
1472 "Content-Type: text/plain; charset=UTF-8\r\n\r\n");
1474 // This body lacks a 'last-chunk' (see RFC 2616)
1475 writer.Write ("10\r\n1234567890123456\r\n");
1477 client.Shutdown (SocketShutdown.Send);
1478 Thread.Sleep (1000);
1483 class AcceptAllPolicy : ICertificatePolicy {
1484 public bool CheckValidationResult (ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
1490 abstract class HttpServer
1492 protected Socket sock;
1493 protected Exception error;
1494 protected ManualResetEvent evt;
1496 public HttpServer ()
1498 sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
1499 sock.Bind (new IPEndPoint (IPAddress.Loopback, 0));
1503 public void Start ()
1505 evt = new ManualResetEvent (false);
1506 Thread th = new Thread (new ThreadStart (Run));
1516 public IPAddress IPAddress {
1517 get { return ((IPEndPoint) sock.LocalEndPoint).Address; }
1521 get { return ((IPEndPoint) sock.LocalEndPoint).Port; }
1524 public Exception Error {
1525 get { return error; }
1528 protected abstract void Run ();
1533 public void BeginGetRequestStream()
1539 r.ContentLength = 0;
1540 r.BeginGetRequestStream((a) =>
1542 using (Stream s = r.EndGetRequestStream(a)) { };
1551 public void BeginGetRequestStreamNoClose()
1556 r.ContentLength = 1;
1557 r.BeginGetRequestStream((a) =>
1559 r.EndGetRequestStream(a);
1568 public void BeginGetRequestStreamCancelIfNotAllBytesWritten()
1574 r.ContentLength = 10;
1575 r.BeginGetRequestStream((a) =>
1577 WebException ex = ExceptionAssert.Throws<WebException>(() =>
1578 { using (Stream s = r.EndGetRequestStream(a)) { }; }
1580 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
1589 public void GetRequestStream2()
1595 r.ContentLength = data64KB.Length;
1596 using (Stream s = r.GetRequestStream())
1598 s.Write(data64KB, 0, data64KB.Length);
1606 public void GetRequestStreamNotAllBytesWritten()
1612 r.ContentLength = data64KB.Length;
1613 WebException ex = ExceptionAssert.Throws<WebException>(() => r.GetRequestStream().Close());
1614 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
1621 public void GetRequestStreamTimeout()
1627 r.ContentLength = data64KB.Length;
1629 WebException ex = ExceptionAssert.Throws<WebException>(() => r.GetRequestStream());
1630 Assert.IsTrue(ex.Status == WebExceptionStatus.Timeout || ex.Status == WebExceptionStatus.ConnectFailure);
1636 public void BeginWrite()
1638 byte[] received = new byte[data64KB.Length];
1644 r.ContentLength = data64KB.Length;
1646 Stream s = r.GetRequestStream();
1648 s.BeginWrite(data64KB, 0, data64KB.Length,
1653 r.GetResponse().Close();
1660 c.Request.InputStream.ReadAll(received, 0, received.Length);
1661 c.Response.StatusCode = 204;
1665 Assert.AreEqual(data64KB, received);
1669 public void BeginWriteAfterAbort()
1671 byte[] received = new byte[data64KB.Length];
1677 r.ContentLength = data64KB.Length;
1679 Stream s = r.GetRequestStream();
1683 WebException ex = ExceptionAssert.Throws<WebException>(() => s.BeginWrite(data64KB, 0, data64KB.Length, null, null));
1684 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
1690 c.Request.InputStream.ReadAll(received, 0, received.Length);
1691 c.Response.StatusCode = 204;
1697 public void PrematureStreamCloseAborts()
1699 byte[] received = new byte[data64KB.Length];
1705 r.ContentLength = data64KB.Length * 2;
1707 Stream s = r.GetRequestStream();
1708 s.Write(data64KB, 0, data64KB.Length);
1710 WebException ex = ExceptionAssert.Throws<WebException>(() => s.Close());
1711 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
1717 c.Request.InputStream.ReadAll(received, 0, received.Length);
1718 c.Response.StatusCode = 204;
1726 byte[] received = new byte[data64KB.Length];
1732 r.ContentLength = data64KB.Length;
1734 using (Stream s = r.GetRequestStream())
1736 s.Write(data64KB, 0, data64KB.Length);
1739 r.GetResponse().Close();
1744 c.Request.InputStream.ReadAll(received, 0, received.Length);
1745 c.Response.StatusCode = 204;
1749 Assert.AreEqual(data64KB, received);
1753 public void WriteServerAborts()
1755 ManualResetEvent abort = new ManualResetEvent(false);
1756 byte[] received = new byte[data64KB.Length];
1762 r.ContentLength = data64KB.Length;
1764 using (Stream s = r.GetRequestStream())
1768 IOException ex = ExceptionAssert.Throws<IOException>(() => s.Write(data64KB, 0, data64KB.Length));
1783 byte[] received = new byte[data64KB.Length];
1788 using (HttpWebResponse x = (HttpWebResponse)r.GetResponse())
1789 using (Stream s = x.GetResponseStream())
1791 s.ReadAll(received, 0, received.Length);
1798 c.Response.StatusCode = 200;
1799 c.Response.ContentLength64 = data64KB.Length;
1800 c.Response.OutputStream.Write(data64KB, 0, data64KB.Length);
1801 c.Response.OutputStream.Close();
1805 Assert.AreEqual(data64KB, received);
1809 public void ReadTimeout2()
1811 byte[] received = new byte[data64KB.Length];
1816 r.ReadWriteTimeout = 10;
1817 using (HttpWebResponse x = (HttpWebResponse)r.GetResponse())
1818 using (Stream s = x.GetResponseStream())
1820 WebException ex = ExceptionAssert.Throws<WebException>(
1821 () => s.ReadAll(received, 0, received.Length));
1822 Assert.AreEqual(ex.Status, WebExceptionStatus.Timeout);
1829 c.Response.StatusCode = 200;
1830 c.Response.ContentLength64 = data64KB.Length;
1831 c.Response.OutputStream.Write(data64KB, 0, data64KB.Length / 2);
1833 c.Response.OutputStream.Write(data64KB, data64KB.Length / 2, data64KB.Length / 2);
1834 c.Response.OutputStream.Close();
1840 public void ReadServerAborted()
1842 byte[] received = new byte[data64KB.Length];
1847 using (HttpWebResponse x = (HttpWebResponse)r.GetResponse())
1848 using (Stream s = x.GetResponseStream())
1850 Assert.AreEqual(1, s.ReadAll(received, 0, received.Length));
1857 c.Response.StatusCode = 200;
1858 c.Response.ContentLength64 = data64KB.Length;
1859 c.Response.OutputStream.Write(data64KB, 0, 1);
1865 public void BeginGetResponse2()
1867 byte[] received = new byte[data64KB.Length];
1872 r.BeginGetResponse((a) =>
1874 using (HttpWebResponse x = (HttpWebResponse)r.EndGetResponse(a))
1875 using (Stream s = x.GetResponseStream())
1877 s.ReadAll(received, 0, received.Length);
1885 c.Response.StatusCode = 200;
1886 c.Response.ContentLength64 = data64KB.Length;
1887 c.Response.OutputStream.Write(data64KB, 0, data64KB.Length);
1888 c.Response.OutputStream.Close();
1892 Assert.AreEqual(data64KB, received);
1896 public void BeginGetResponseAborts()
1898 ManualResetEvent aborted = new ManualResetEvent(false);
1903 r.BeginGetResponse((a) =>
1905 WebException ex = ExceptionAssert.Throws<WebException>(() => r.EndGetResponse(a));
1906 Assert.AreEqual(ex.Status, WebExceptionStatus.RequestCanceled);
1917 c.Response.StatusCode = 200;
1918 c.Response.ContentLength64 = 0;
1923 private void DoRequest(Action<HttpWebRequest, EventWaitHandle> request)
1925 int port = rand.Next(20000, 65535);
1927 ManualResetEvent completed = new ManualResetEvent(false);
1928 Uri address = new Uri(string.Format("http://localhost:{0}", port));
1929 HttpWebRequest client = (HttpWebRequest)WebRequest.Create(address);
1931 request(client, completed);
1933 if (!completed.WaitOne(10000))
1935 Assert.Fail("Test hung");
1939 private void DoRequest(Action<HttpWebRequest, EventWaitHandle> request, Action<HttpListenerContext> processor)
1941 int port = rand.Next(20000, 65535);
1943 ManualResetEvent[] completed = new ManualResetEvent[2];
1944 completed[0] = new ManualResetEvent(false);
1945 completed[1] = new ManualResetEvent(false);
1947 using (ListenerScope scope = new ListenerScope(processor, port, completed[0]))
1949 ManualResetEvent clientCompleted = new ManualResetEvent(false);
1950 Uri address = new Uri(string.Format("http://localhost:{0}", port));
1951 HttpWebRequest client = (HttpWebRequest)WebRequest.Create(address);
1953 ThreadPool.QueueUserWorkItem((o) => request(client, completed[1]));
1955 if (!WaitHandle.WaitAll(completed, 10000))
1957 Assert.Fail("Test hung.");
1962 private class ListenerScope : IDisposable
1964 EventWaitHandle completed;
1965 public HttpListener listener;
1966 Action<HttpListenerContext> processor;
1968 public ListenerScope(Action<HttpListenerContext> processor, int port, EventWaitHandle completed)
1970 this.processor = processor;
1971 this.completed = completed;
1973 this.listener = new HttpListener();
1974 this.listener.Prefixes.Add(string.Format("http://localhost:{0}/", port));
1975 this.listener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
1976 this.listener.Start();
1978 this.listener.BeginGetContext(this.RequestHandler, null);
1981 private void RequestHandler(IAsyncResult result)
1983 HttpListenerContext context = null;
1987 context = this.listener.EndGetContext(result);
1989 catch (HttpListenerException ex)
1991 // check if the thread has been aborted as in the case when we are shutting down.
1992 if (ex.ErrorCode == 995)
1997 catch (ObjectDisposedException)
2002 ThreadPool.QueueUserWorkItem(
2003 (o) => { try { this.processor(context); } catch (HttpListenerException) {} });
2005 this.completed.Set();
2008 public void Dispose()
2010 this.listener.Stop();
2015 class SslHttpServer : HttpServer {
2016 X509Certificate _certificate;
2018 protected override void Run ()
2021 Socket client = sock.Accept ();
2022 NetworkStream ns = new NetworkStream (client, true);
2023 SslServerStream s = new SslServerStream (ns, Certificate, false, false);
2024 s.PrivateKeyCertSelectionDelegate += new PrivateKeySelectionCallback (GetPrivateKey);
2026 StreamReader reader = new StreamReader (s);
2027 StreamWriter writer = new StreamWriter (s, Encoding.ASCII);
2030 string hello = "<html><body><h1>Hello World!</h1></body></html>";
2031 string answer = "HTTP/1.0 200\r\n" +
2032 "Connection: close\r\n" +
2033 "Content-Type: text/html\r\n" +
2034 "Content-Encoding: " + Encoding.ASCII.WebName + "\r\n" +
2035 "Content-Length: " + hello.Length + "\r\n" +
2040 line = reader.ReadLine ();
2041 } while (line != "" && line != null && line.Length > 0);
2043 // Now the content. We know it's 100 bytes.
2044 // This makes BeginRead in sslclientstream block.
2045 char [] cs = new char [100];
2046 reader.Read (cs, 0, 100);
2048 writer.Write (answer);
2050 evt.WaitOne (50000, false);
2051 } catch (Exception e) {
2056 X509Certificate Certificate {
2058 if (_certificate == null)
2059 _certificate = new X509Certificate (CertData.Certificate);
2061 return _certificate;
2065 AsymmetricAlgorithm GetPrivateKey (X509Certificate certificate, string targetHost)
2067 PrivateKey key = new PrivateKey (CertData.PrivateKey, null);
2073 public readonly static byte [] Certificate = {
2074 48, 130, 1, 191, 48, 130, 1, 40, 160, 3, 2, 1, 2, 2, 16, 36,
2075 14, 97, 190, 146, 132, 208, 71, 175, 6, 87, 168, 185, 175, 55, 43, 48,
2076 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 48, 18,
2077 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103, 111, 110, 122, 97,
2078 108, 111, 48, 30, 23, 13, 48, 53, 48, 54, 50, 50, 49, 57, 51, 48,
2079 52, 54, 90, 23, 13, 51, 57, 49, 50, 51, 49, 50, 51, 53, 57, 53,
2080 57, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 3, 19, 7, 103,
2081 111, 110, 122, 97, 108, 111, 48, 129, 158, 48, 13, 6, 9, 42, 134, 72,
2082 134, 247, 13, 1, 1, 1, 5, 0, 3, 129, 140, 0, 48, 129, 136, 2,
2083 129, 129, 0, 138, 9, 38, 25, 166, 252, 59, 26, 39, 184, 128, 216, 38,
2084 73, 41, 86, 30, 228, 160, 205, 41, 135, 115, 223, 44, 62, 42, 198, 178,
2085 190, 81, 11, 25, 21, 216, 49, 179, 130, 246, 52, 97, 175, 212, 94, 157,
2086 231, 162, 66, 161, 103, 63, 204, 83, 141, 172, 119, 97, 225, 206, 98, 101,
2087 210, 106, 2, 206, 81, 90, 173, 47, 41, 199, 209, 241, 177, 177, 96, 207,
2088 254, 220, 190, 66, 180, 153, 0, 209, 14, 178, 69, 194, 3, 37, 116, 239,
2089 49, 23, 185, 245, 255, 126, 35, 85, 246, 56, 244, 107, 117, 24, 14, 57,
2090 9, 111, 147, 189, 220, 142, 57, 104, 153, 193, 205, 19, 14, 22, 157, 16,
2091 24, 80, 201, 2, 2, 0, 17, 163, 23, 48, 21, 48, 19, 6, 3, 85,
2092 29, 37, 4, 12, 48, 10, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1,
2093 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 4, 5, 0, 3,
2094 129, 129, 0, 64, 49, 57, 253, 218, 198, 229, 51, 189, 12, 154, 225, 183,
2095 160, 147, 90, 113, 172, 69, 122, 28, 77, 97, 215, 231, 194, 150, 29, 196,
2096 65, 95, 218, 99, 142, 111, 79, 205, 109, 76, 32, 92, 220, 76, 88, 53,
2097 237, 80, 11, 85, 44, 91, 21, 210, 12, 34, 223, 234, 18, 187, 136, 62,
2098 26, 240, 103, 180, 12, 226, 221, 250, 247, 129, 51, 23, 129, 165, 56, 67,
2099 43, 83, 244, 110, 207, 24, 253, 195, 16, 46, 80, 113, 80, 18, 2, 254,
2100 120, 147, 151, 164, 23, 210, 230, 100, 19, 197, 179, 28, 194, 48, 106, 159,
2101 155, 144, 37, 82, 44, 160, 40, 52, 146, 174, 77, 188, 160, 230, 75, 172,
2105 public readonly static byte [] PrivateKey = {
2106 30, 241, 181, 176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
2107 0, 0, 0, 0, 84, 2, 0, 0, 7, 2, 0, 0, 0, 36, 0, 0,
2108 82, 83, 65, 50, 0, 4, 0, 0, 17, 0, 0, 0, 201, 80, 24, 16,
2109 157, 22, 14, 19, 205, 193, 153, 104, 57, 142, 220, 189, 147, 111, 9, 57,
2110 14, 24, 117, 107, 244, 56, 246, 85, 35, 126, 255, 245, 185, 23, 49, 239,
2111 116, 37, 3, 194, 69, 178, 14, 209, 0, 153, 180, 66, 190, 220, 254, 207,
2112 96, 177, 177, 241, 209, 199, 41, 47, 173, 90, 81, 206, 2, 106, 210, 101,
2113 98, 206, 225, 97, 119, 172, 141, 83, 204, 63, 103, 161, 66, 162, 231, 157,
2114 94, 212, 175, 97, 52, 246, 130, 179, 49, 216, 21, 25, 11, 81, 190, 178,
2115 198, 42, 62, 44, 223, 115, 135, 41, 205, 160, 228, 30, 86, 41, 73, 38,
2116 216, 128, 184, 39, 26, 59, 252, 166, 25, 38, 9, 138, 175, 88, 190, 223,
2117 27, 24, 224, 123, 190, 69, 164, 234, 129, 59, 108, 229, 248, 62, 187, 15,
2118 235, 147, 162, 83, 47, 123, 170, 190, 224, 31, 215, 110, 143, 31, 227, 216,
2119 85, 88, 154, 83, 207, 229, 41, 28, 237, 116, 181, 17, 37, 141, 224, 185,
2120 164, 144, 141, 233, 164, 138, 177, 241, 115, 181, 230, 150, 7, 92, 139, 141,
2121 113, 95, 57, 191, 211, 165, 217, 250, 197, 68, 164, 184, 168, 43, 48, 65,
2122 177, 237, 173, 144, 148, 221, 62, 189, 147, 63, 216, 188, 206, 103, 226, 171,
2123 32, 20, 230, 116, 144, 192, 1, 39, 202, 87, 74, 250, 6, 142, 188, 23,
2124 45, 4, 112, 191, 253, 67, 69, 70, 128, 143, 44, 234, 41, 96, 195, 82,
2125 202, 35, 158, 149, 240, 151, 23, 25, 166, 179, 85, 144, 58, 120, 149, 229,
2126 205, 34, 8, 110, 86, 119, 130, 210, 37, 173, 65, 71, 169, 67, 8, 51,
2127 20, 96, 51, 155, 3, 39, 85, 187, 40, 193, 57, 19, 99, 78, 173, 28,
2128 129, 154, 108, 175, 8, 138, 237, 71, 27, 148, 129, 35, 47, 57, 101, 237,
2129 168, 178, 227, 221, 212, 63, 124, 254, 253, 215, 183, 159, 49, 103, 74, 49,
2130 67, 160, 171, 72, 194, 215, 108, 251, 178, 18, 184, 100, 211, 105, 21, 186,
2131 39, 66, 218, 154, 72, 222, 90, 237, 179, 251, 51, 224, 212, 56, 251, 6,
2132 209, 151, 198, 176, 89, 110, 35, 141, 248, 237, 223, 68, 135, 206, 207, 169,
2133 254, 219, 243, 130, 71, 11, 94, 113, 233, 92, 63, 156, 169, 72, 215, 110,
2134 95, 94, 191, 50, 59, 89, 187, 59, 183, 99, 161, 146, 233, 245, 219, 80,
2135 87, 113, 251, 50, 144, 195, 158, 46, 189, 232, 119, 91, 75, 22, 6, 176,
2136 39, 206, 25, 196, 213, 195, 219, 24, 28, 103, 104, 36, 137, 128, 4, 119,
2137 163, 40, 126, 87, 18, 86, 128, 243, 213, 101, 2, 237, 78, 64, 160, 55,
2138 199, 93, 90, 126, 175, 199, 55, 89, 234, 190, 5, 16, 196, 88, 28, 208,
2139 28, 92, 32, 115, 204, 9, 202, 101, 15, 123, 43, 75, 90, 144, 95, 179,
2140 102, 249, 57, 150, 204, 99, 147, 203, 16, 63, 81, 244, 226, 237, 82, 204,
2141 20, 200, 140, 65, 83, 217, 161, 23, 123, 37, 115, 12, 100, 73, 70, 190,
2142 32, 235, 174, 140, 148, 157, 47, 238, 40, 208, 228, 80, 54, 187, 156, 252,
2143 253, 230, 231, 156, 138, 125, 96, 79, 3, 27, 143, 55, 146, 169, 165, 61,
2144 238, 60, 227, 77, 217, 93, 117, 122, 111, 46, 173, 113,
2150 public static class StreamExtensions
2152 public static int ReadAll(this Stream stream, byte[] buffer, int offset, int count)
2156 while (totalRead < count)
2158 int bytesRead = stream.Read(buffer, offset + totalRead, count - totalRead);
2165 totalRead += bytesRead;
2172 public class ExceptionAssert
2175 /// Asserts that the function throws an exception.
2177 /// <param name="f">A function execute that is expected to raise an exception.</param>
2178 /// <typeparam name="T">The type of exception that is expected.</typeparam>
2179 /// <returns>The exception thrown.</returns>
2180 /// <exception cref="AssertFailedException">If the function does not throw an exception
2181 /// or throws a different exception.</exception>
2182 /// <example><![CDATA[
2183 /// ExceptionAssert.Throws(typeof(ArgumentNullException), delegate {
2184 /// myObject.myFunction(null); });
2186 public static T Throws<T>(Action f) where T : Exception
2188 Exception actualException = null;
2194 catch (Exception ex)
2196 actualException = ex;
2199 if (actualException == null)
2201 throw new AssertionException(string.Format(
2202 "No exception thrown. Expected '{0}'",
2203 typeof(T).FullName));
2205 else if (typeof(T) != actualException.GetType())
2207 throw new AssertionException(string.Format(
2208 "Caught exception of type '{0}'. Expected '{1}':{2}",
2209 actualException.GetType().FullName,
2211 Environment.NewLine + actualException));
2214 return (T)actualException;