37c40d7445e070cd8d5021dc238253b6bdac5db5
[mono.git] / mcs / class / System / Test / System.Net / CookieParserTest.cs
1 using System;
2 using System.IO;
3 using System.Threading;
4 using System.Globalization;
5 using System.Net;
6 using System.Net.Sockets;
7 using NUnit.Framework;
8
9 namespace MonoTests.System.Net
10 {
11         [TestFixture]
12         [Category ("RequiresBSDSockets")]
13         public class CookieParserTest
14         {
15                 public const string A = "Foo=Bar, expires=World; expires=Sat, 11-Oct-14 22:45:19 GMT, A=B";
16                 public const string B = "A=B=C, expires=Sat, 99-Dec-01 01:00:00 XDT; Hello=World, Foo=Bar";
17                 // Only the invariant culture is allowed.
18                 public const string C = "Foo=Bar, expires=Montag, 21. Juni 2012 23:11:45";
19                 // Only comma serves as separation character.
20                 public const string D = "A=B, C=D; E=F, G=H";
21                 public const string E = "A; C; expires=Tue, 25-Jun-19 00:51:34 GMT, E=F";
22                 public const string F = "Foo = \" A, B\"C D, E=F";
23
24                 CookieCollection DoRequest (string header)
25                 {
26                         HttpWebResponse res;
27                         using (var listener = new Listener ("Set-Cookie: " + header)) {
28                                 var req = (HttpWebRequest)HttpWebRequest.Create (listener.URI);
29                                 req.CookieContainer = new CookieContainer ();
30                                 req.Method = "POST";
31                                 res = (HttpWebResponse)req.GetResponse ();
32                         }
33
34                         Assert.AreEqual (header, res.Headers.Get ("Set-Cookie"));
35                         return res.Cookies;
36                 }
37
38                 void AssertCookie (Cookie cookie, string name, string value, long ticks)
39                 {
40                         AssertCookie (cookie, name, value);
41                         if (ticks == 0)
42                                 Assert.AreEqual (0, cookie.Expires.Ticks);
43                         else
44                                 Assert.AreEqual (ticks, cookie.Expires.ToUniversalTime ().Ticks);
45                 }
46
47                 void AssertCookie (Cookie cookie, string name, string value)
48                 {
49                         Assert.AreEqual (name, cookie.Name);
50                         Assert.AreEqual (value, cookie.Value);
51                 }
52
53                 [Test]
54                 public void TestDate ()
55                 {
56                         var d1 = "Sat, 11-Oct-14 22:45:19 GMT";
57                         var d2 = "Tue, 25-Jun-19 00:51:34 GMT";
58
59                         var format = "ddd, dd'-'MMM'-'yy HH':'mm':'ss 'GMT'";
60                         var p1 = DateTime.ParseExact (d1, format, CultureInfo.InvariantCulture);
61                         p1 = DateTime.SpecifyKind (p1, DateTimeKind.Utc);
62
63                         Assert.AreEqual ("10/11/2014 22:45:19", p1.ToString ("G", CultureInfo.InvariantCulture));
64                         Assert.AreEqual (p1.Ticks, p1.ToUniversalTime ().Ticks);
65                         Assert.AreEqual (635486643190000000, p1.Ticks);
66
67                         var p2 = DateTime.ParseExact (d2, format, CultureInfo.InvariantCulture);
68                         p2 = DateTime.SpecifyKind (p2, DateTimeKind.Utc);
69                         Assert.AreEqual ("06/25/2019 00:51:34", p2.ToString ("G", CultureInfo.InvariantCulture));
70                         Assert.AreEqual (p2.Ticks, p2.ToUniversalTime ().Ticks);
71                         Assert.AreEqual (636970206940000000, p2.Ticks);
72                 }
73
74                 [Test]
75                 public void TestExpires ()
76                 {
77                         var cookies = DoRequest (A);
78                         Assert.AreEqual (3, cookies.Count);
79                         AssertCookie (cookies [0], "Foo", "Bar", 0);
80                         AssertCookie (cookies [1], "expires", "World", 635486643190000000);
81                         AssertCookie (cookies [2], "A", "B", 0);
82                 }
83
84                 [Test]
85                 public void TestInvalidCookie ()
86                 {
87                         var cookies = DoRequest (B);
88                         Assert.AreEqual (3, cookies.Count);
89                         AssertCookie (cookies [0], "A", "B=C");
90                         AssertCookie (cookies [1], "expires", "Sat");
91                         AssertCookie (cookies [2], "Foo", "Bar");
92                 }
93
94                 [Test]
95                 public void TestLocalCulture ()
96                 {
97                         var old = Thread.CurrentThread.CurrentCulture;
98                         try {
99                                 var culture = new CultureInfo ("de-DE");
100                                 Thread.CurrentThread.CurrentCulture = culture;
101
102                                 var cookies = DoRequest (C);
103                                 Assert.AreEqual (2, cookies.Count);
104                                 AssertCookie (cookies [0], "Foo", "Bar");
105                                 AssertCookie (cookies [1], "expires", "Montag");
106                         } finally {
107                                 Thread.CurrentThread.CurrentCulture = old;
108                         }
109                 }
110
111                 [Test]
112                 public void TestMultiple ()
113                 {
114                         var cookies = DoRequest (D);
115                         Assert.AreEqual (3, cookies.Count);
116                         AssertCookie (cookies [0], "A", "B");
117                         AssertCookie (cookies [1], "C", "D");
118                         AssertCookie (cookies [2], "G", "H");
119                 }
120
121                 [Test]
122                 public void TestMultiple2 ()
123                 {
124                         var cookies = DoRequest (E);
125                         Assert.AreEqual (2, cookies.Count);
126                         AssertCookie (cookies [0], "A", string.Empty, 636970206940000000);
127                         AssertCookie (cookies [1], "E", "F");
128                 }
129
130                 [Test]
131                 public void TestQuotation ()
132                 {
133                         var cookies = DoRequest (F);
134                         Assert.AreEqual (2, cookies.Count);
135                         AssertCookie (cookies [0], "Foo", "\" A, B\"");
136                         AssertCookie (cookies [1], "E", "F");
137                 }
138
139                 public class Listener : IDisposable
140                 {
141                         Socket socket;
142                         string[] headers;
143
144                         public Listener (params string[] headers)
145                         {
146                                 this.headers = headers;
147                                 Start ();
148                         }
149
150                         void Start ()
151                         {
152                                 socket = new Socket (
153                                         AddressFamily.InterNetwork, SocketType.Stream,
154                                         ProtocolType.Tcp);
155                                 socket.Bind (new IPEndPoint (IPAddress.Loopback, 0));
156                                 socket.Listen (1);
157                                 socket.BeginAccept ((result) => {
158                                         var accepted = socket.EndAccept (result);
159                                         HandleRequest (accepted);
160                                 }, null);
161                         }
162
163                         public void Dispose ()
164                         {
165                                 if (socket != null) {
166                                         socket.Close ();
167                                         socket = null;
168                                 }
169                         }
170
171                         void HandleRequest (Socket accepted)
172                         {
173                                 using (var stream = new NetworkStream (accepted)) {
174                                         using (var writer = new StreamWriter (stream)) {
175                                                 writer.WriteLine ("HTTP/1.1 200 OK");
176                                                 writer.WriteLine ("Content-Type: text/plain");
177                                                 foreach (var header in headers)
178                                                         writer.WriteLine (header);
179                                                 writer.WriteLine ();
180                                                 writer.WriteLine ("HELLO");
181                                         }
182                                 }
183                         }
184
185                         public EndPoint EndPoint {
186                                 get { return socket.LocalEndPoint; }
187                         }
188
189                         public string URI {
190                                 get { return string.Format ("http://{0}/", EndPoint); }
191                         }
192                 }
193         }
194 }