1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/cookies/canonical_cookie.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "net/cookies/cookie_constants.h"
9#include "net/cookies/cookie_options.h"
10#include "testing/gtest/include/gtest/gtest.h"
11#include "url/gurl.h"
12
13namespace net {
14
15TEST(CanonicalCookieTest, GetCookieSourceFromURL) {
16  EXPECT_EQ("http://example.com/",
17            CanonicalCookie::GetCookieSourceFromURL(
18                GURL("http://example.com")));
19  EXPECT_EQ("http://example.com/",
20            CanonicalCookie::GetCookieSourceFromURL(
21                GURL("http://example.com/")));
22  EXPECT_EQ("http://example.com/",
23            CanonicalCookie::GetCookieSourceFromURL(
24                GURL("http://example.com/test")));
25  EXPECT_EQ("file:///tmp/test.html",
26            CanonicalCookie::GetCookieSourceFromURL(
27                GURL("file:///tmp/test.html")));
28  EXPECT_EQ("http://example.com/",
29            CanonicalCookie::GetCookieSourceFromURL(
30                GURL("http://example.com:1234/")));
31  EXPECT_EQ("http://example.com/",
32            CanonicalCookie::GetCookieSourceFromURL(
33                GURL("https://example.com/")));
34  EXPECT_EQ("http://example.com/",
35            CanonicalCookie::GetCookieSourceFromURL(
36                GURL("http://user:pwd@example.com/")));
37  EXPECT_EQ("http://example.com/",
38            CanonicalCookie::GetCookieSourceFromURL(
39                GURL("http://example.com/test?foo")));
40  EXPECT_EQ("http://example.com/",
41            CanonicalCookie::GetCookieSourceFromURL(
42                GURL("http://example.com/test#foo")));
43}
44
45TEST(CanonicalCookieTest, Constructor) {
46  GURL url("http://www.example.com/test");
47  base::Time current_time = base::Time::Now();
48
49  CanonicalCookie cookie(url, "A", "2", "www.example.com", "/test",
50                         current_time, base::Time(), current_time, false, false,
51                         COOKIE_PRIORITY_DEFAULT);
52  EXPECT_EQ(url.GetOrigin().spec(), cookie.Source());
53  EXPECT_EQ("A", cookie.Name());
54  EXPECT_EQ("2", cookie.Value());
55  EXPECT_EQ("www.example.com", cookie.Domain());
56  EXPECT_EQ("/test", cookie.Path());
57  EXPECT_FALSE(cookie.IsSecure());
58
59  CanonicalCookie cookie2(url,
60                          "A",
61                          "2",
62                          std::string(),
63                          std::string(),
64                          current_time,
65                          base::Time(),
66                          current_time,
67                          false,
68                          false,
69                          COOKIE_PRIORITY_DEFAULT);
70  EXPECT_EQ(url.GetOrigin().spec(), cookie.Source());
71  EXPECT_EQ("A", cookie2.Name());
72  EXPECT_EQ("2", cookie2.Value());
73  EXPECT_EQ("", cookie2.Domain());
74  EXPECT_EQ("", cookie2.Path());
75  EXPECT_FALSE(cookie2.IsSecure());
76
77}
78
79TEST(CanonicalCookieTest, Create) {
80  // Test creating cookies from a cookie string.
81  GURL url("http://www.example.com/test/foo.html");
82  base::Time creation_time = base::Time::Now();
83  CookieOptions options;
84
85  scoped_ptr<CanonicalCookie> cookie(
86        CanonicalCookie::Create(url, "A=2", creation_time, options));
87  EXPECT_EQ(url.GetOrigin().spec(), cookie->Source());
88  EXPECT_EQ("A", cookie->Name());
89  EXPECT_EQ("2", cookie->Value());
90  EXPECT_EQ("www.example.com", cookie->Domain());
91  EXPECT_EQ("/test", cookie->Path());
92  EXPECT_FALSE(cookie->IsSecure());
93
94  GURL url2("http://www.foo.com");
95  cookie.reset(CanonicalCookie::Create(url2, "B=1", creation_time, options));
96  EXPECT_EQ(url2.GetOrigin().spec(), cookie->Source());
97  EXPECT_EQ("B", cookie->Name());
98  EXPECT_EQ("1", cookie->Value());
99  EXPECT_EQ("www.foo.com", cookie->Domain());
100  EXPECT_EQ("/", cookie->Path());
101  EXPECT_FALSE(cookie->IsSecure());
102
103  // Test creating secure cookies. RFC 6265 allows insecure urls to set secure
104  // cookies.
105  cookie.reset(
106      CanonicalCookie::Create(url, "A=2; Secure", creation_time, options));
107  EXPECT_TRUE(cookie.get());
108  EXPECT_TRUE(cookie->IsSecure());
109
110  // Test creating http only cookies.
111  cookie.reset(
112      CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, options));
113  EXPECT_FALSE(cookie.get());
114  CookieOptions httponly_options;
115  httponly_options.set_include_httponly();
116  cookie.reset(
117      CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time,
118                              httponly_options));
119  EXPECT_TRUE(cookie->IsHttpOnly());
120
121  // Test the creating cookies using specific parameter instead of a cookie
122  // string.
123  cookie.reset(CanonicalCookie::Create(
124      url, "A", "2", "www.example.com", "/test", creation_time, base::Time(),
125      false, false, COOKIE_PRIORITY_DEFAULT));
126  EXPECT_EQ(url.GetOrigin().spec(), cookie->Source());
127  EXPECT_EQ("A", cookie->Name());
128  EXPECT_EQ("2", cookie->Value());
129  EXPECT_EQ(".www.example.com", cookie->Domain());
130  EXPECT_EQ("/test", cookie->Path());
131  EXPECT_FALSE(cookie->IsSecure());
132
133  cookie.reset(CanonicalCookie::Create(
134      url, "A", "2", ".www.example.com", "/test", creation_time, base::Time(),
135      false, false, COOKIE_PRIORITY_DEFAULT));
136  EXPECT_EQ(url.GetOrigin().spec(), cookie->Source());
137  EXPECT_EQ("A", cookie->Name());
138  EXPECT_EQ("2", cookie->Value());
139  EXPECT_EQ(".www.example.com", cookie->Domain());
140  EXPECT_EQ("/test", cookie->Path());
141  EXPECT_FALSE(cookie->IsSecure());
142}
143
144TEST(CanonicalCookieTest, EmptyExpiry) {
145  GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
146  base::Time creation_time = base::Time::Now();
147  CookieOptions options;
148
149  std::string cookie_line =
150      "ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
151  scoped_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
152      url, cookie_line, creation_time, options));
153  EXPECT_TRUE(cookie.get());
154  EXPECT_FALSE(cookie->IsPersistent());
155  EXPECT_FALSE(cookie->IsExpired(creation_time));
156  EXPECT_EQ(base::Time(), cookie->ExpiryDate());
157
158  // With a stale server time
159  options.set_server_time(creation_time - base::TimeDelta::FromHours(1));
160  cookie.reset(CanonicalCookie::Create(
161      url, cookie_line, creation_time, options));
162  EXPECT_TRUE(cookie.get());
163  EXPECT_FALSE(cookie->IsPersistent());
164  EXPECT_FALSE(cookie->IsExpired(creation_time));
165  EXPECT_EQ(base::Time(), cookie->ExpiryDate());
166
167  // With a future server time
168  options.set_server_time(creation_time + base::TimeDelta::FromHours(1));
169  cookie.reset(CanonicalCookie::Create(
170      url, cookie_line, creation_time, options));
171  EXPECT_TRUE(cookie.get());
172  EXPECT_FALSE(cookie->IsPersistent());
173  EXPECT_FALSE(cookie->IsExpired(creation_time));
174  EXPECT_EQ(base::Time(), cookie->ExpiryDate());
175}
176
177TEST(CanonicalCookieTest, IsEquivalent) {
178  GURL url("http://www.example.com/");
179  std::string cookie_name = "A";
180  std::string cookie_value = "2EDA-EF";
181  std::string cookie_domain = ".www.example.com";
182  std::string cookie_path = "/";
183  base::Time creation_time = base::Time::Now();
184  base::Time last_access_time = creation_time;
185  base::Time expiration_time = creation_time + base::TimeDelta::FromDays(2);
186  bool secure(false);
187  bool httponly(false);
188
189  // Test that a cookie is equivalent to itself.
190  scoped_ptr<CanonicalCookie> cookie(
191      new CanonicalCookie(url, cookie_name, cookie_value, cookie_domain,
192                          cookie_path, creation_time, expiration_time,
193                          last_access_time, secure, httponly,
194                          COOKIE_PRIORITY_MEDIUM));
195  EXPECT_TRUE(cookie->IsEquivalent(*cookie));
196
197  // Test that two identical cookies are equivalent.
198  scoped_ptr<CanonicalCookie> other_cookie(
199      new CanonicalCookie(url, cookie_name, cookie_value, cookie_domain,
200                          cookie_path, creation_time, expiration_time,
201                          last_access_time, secure, httponly,
202                          COOKIE_PRIORITY_MEDIUM));
203  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
204
205  // Tests that use different variations of attribute values that
206  // DON'T affect cookie equivalence.
207  other_cookie.reset(new CanonicalCookie(url, cookie_name, "2", cookie_domain,
208                                         cookie_path, creation_time,
209                                         expiration_time, last_access_time,
210                                         secure, httponly,
211                                         COOKIE_PRIORITY_HIGH));
212  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
213
214  base::Time other_creation_time =
215      creation_time + base::TimeDelta::FromMinutes(2);
216  other_cookie.reset(new CanonicalCookie(url, cookie_name, "2", cookie_domain,
217                                         cookie_path, other_creation_time,
218                                         expiration_time, last_access_time,
219                                         secure, httponly,
220                                         COOKIE_PRIORITY_MEDIUM));
221  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
222
223  other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_name,
224                                         cookie_domain, cookie_path,
225                                         creation_time, expiration_time,
226                                         last_access_time, true, httponly,
227                                         COOKIE_PRIORITY_LOW));
228  EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
229
230  // Tests that use different variations of attribute values that
231  // DO affect cookie equivalence.
232  other_cookie.reset(new CanonicalCookie(url, "B", cookie_value, cookie_domain,
233                                         cookie_path, creation_time,
234                                         expiration_time, last_access_time,
235                                         secure, httponly,
236                                         COOKIE_PRIORITY_MEDIUM));
237  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
238
239  other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_value,
240                                         "www.example.com", cookie_path,
241                                         creation_time, expiration_time,
242                                         last_access_time, secure, httponly,
243                                         COOKIE_PRIORITY_MEDIUM));
244  EXPECT_TRUE(cookie->IsDomainCookie());
245  EXPECT_FALSE(other_cookie->IsDomainCookie());
246  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
247
248  other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_value,
249                                         ".example.com", cookie_path,
250                                         creation_time, expiration_time,
251                                         last_access_time, secure, httponly,
252                                         COOKIE_PRIORITY_MEDIUM));
253  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
254
255  other_cookie.reset(new CanonicalCookie(url, cookie_name, cookie_value,
256                                         cookie_domain, "/test/0",
257                                         creation_time, expiration_time,
258                                         last_access_time, secure, httponly,
259                                         COOKIE_PRIORITY_MEDIUM));
260  EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
261}
262
263TEST(CanonicalCookieTest, IsDomainMatch) {
264  GURL url("http://www.example.com/test/foo.html");
265  base::Time creation_time = base::Time::Now();
266  CookieOptions options;
267
268  scoped_ptr<CanonicalCookie> cookie(
269      CanonicalCookie::Create(url, "A=2", creation_time, options));
270  EXPECT_TRUE(cookie->IsHostCookie());
271  EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
272  EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
273  EXPECT_FALSE(cookie->IsDomainMatch("foo.www.example.com"));
274  EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
275  EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
276
277  cookie.reset(
278      CanonicalCookie::Create(url, "A=2; Domain=www.example.com", creation_time,
279                              options));
280  EXPECT_TRUE(cookie->IsDomainCookie());
281  EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
282  EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
283  EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
284  EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
285  EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
286
287  cookie.reset(
288      CanonicalCookie::Create(url, "A=2; Domain=.www.example.com",
289                              creation_time, options));
290  EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
291  EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
292  EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
293  EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
294  EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
295}
296
297TEST(CanonicalCookieTest, IsOnPath) {
298  base::Time creation_time = base::Time::Now();
299  CookieOptions options;
300
301  scoped_ptr<CanonicalCookie> cookie(
302      CanonicalCookie::Create(GURL("http://www.example.com"),
303                              "A=2", creation_time, options));
304  EXPECT_TRUE(cookie->IsOnPath("/"));
305  EXPECT_TRUE(cookie->IsOnPath("/test"));
306  EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
307
308  // Test the empty string edge case.
309  EXPECT_FALSE(cookie->IsOnPath(std::string()));
310
311  cookie.reset(
312      CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
313                              "A=2", creation_time, options));
314  EXPECT_FALSE(cookie->IsOnPath("/"));
315  EXPECT_TRUE(cookie->IsOnPath("/test"));
316  EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
317  EXPECT_TRUE(cookie->IsOnPath("/test/sample/bar.html"));
318}
319
320TEST(CanonicalCookieTest, IncludeForRequestURL) {
321  GURL url("http://www.example.com");
322  base::Time creation_time = base::Time::Now();
323  CookieOptions options;
324
325  scoped_ptr<CanonicalCookie> cookie(
326      CanonicalCookie::Create(url, "A=2", creation_time, options));
327  EXPECT_TRUE(cookie->IncludeForRequestURL(url, options));
328  EXPECT_TRUE(cookie->IncludeForRequestURL(
329      GURL("http://www.example.com/foo/bar"), options));
330  EXPECT_TRUE(cookie->IncludeForRequestURL(
331      GURL("https://www.example.com/foo/bar"), options));
332  EXPECT_FALSE(cookie->IncludeForRequestURL(GURL("https://sub.example.com"),
333                                            options));
334  EXPECT_FALSE(cookie->IncludeForRequestURL(GURL("https://sub.www.example.com"),
335                                            options));
336
337  // Test that cookie with a cookie path that does not match the url path are
338  // not included.
339  cookie.reset(CanonicalCookie::Create(url, "A=2; Path=/foo/bar", creation_time,
340                                       options));
341  EXPECT_FALSE(cookie->IncludeForRequestURL(url, options));
342  EXPECT_TRUE(cookie->IncludeForRequestURL(
343      GURL("http://www.example.com/foo/bar/index.html"), options));
344
345  // Test that a secure cookie is not included for a non secure URL.
346  GURL secure_url("https://www.example.com");
347  cookie.reset(CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
348                                       options));
349  EXPECT_TRUE(cookie->IsSecure());
350  EXPECT_TRUE(cookie->IncludeForRequestURL(secure_url, options));
351  EXPECT_FALSE(cookie->IncludeForRequestURL(url, options));
352
353  // Test that http only cookies are only included if the include httponly flag
354  // is set on the cookie options.
355  options.set_include_httponly();
356  cookie.reset(
357      CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, options));
358  EXPECT_TRUE(cookie->IsHttpOnly());
359  EXPECT_TRUE(cookie->IncludeForRequestURL(url, options));
360  options.set_exclude_httponly();
361  EXPECT_FALSE(cookie->IncludeForRequestURL(url, options));
362}
363
364}  // namespace net
365