• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Chromium Authors
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/http/http_cookie_indices.h"
6 
7 #include "net/cookies/cookie_util.h"
8 #include "net/http/http_response_headers.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace net {
13 namespace {
14 
15 using cookie_util::ParsedRequestCookies;
16 using ::testing::ElementsAre;
17 using ::testing::Optional;
18 
19 constexpr std::string_view kCookieIndicesHeader = "Cookie-Indices";
20 
TEST(CookieIndicesTest,Absent)21 TEST(CookieIndicesTest, Absent) {
22   auto headers =
23       HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK").Build();
24   auto result = ParseCookieIndices(*headers);
25   EXPECT_FALSE(result.has_value());
26 }
27 
TEST(CookieIndicesTest,PresentButEmpty)28 TEST(CookieIndicesTest, PresentButEmpty) {
29   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
30                      .AddHeader(kCookieIndicesHeader, "")
31                      .Build();
32   auto result = ParseCookieIndices(*headers);
33   EXPECT_THAT(result, Optional(ElementsAre()));
34 }
35 
TEST(CookieIndicesTest,OneCookie)36 TEST(CookieIndicesTest, OneCookie) {
37   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
38                      .AddHeader(kCookieIndicesHeader, R"("alpha")")
39                      .Build();
40   auto result = ParseCookieIndices(*headers);
41   EXPECT_THAT(result, Optional(ElementsAre("alpha")));
42 }
43 
TEST(CookieIndicesTest,SeveralCookies)44 TEST(CookieIndicesTest, SeveralCookies) {
45   auto headers =
46       HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
47           .AddHeader(kCookieIndicesHeader, R"("alpha", "bravo")")
48           .AddHeader(kCookieIndicesHeader, R"("charlie", "delta", "echo")")
49           .Build();
50   auto result = ParseCookieIndices(*headers);
51   EXPECT_THAT(result, Optional(ElementsAre("alpha", "bravo", "charlie", "delta",
52                                            "echo")));
53 }
54 
TEST(CookieIndicesTest,NonRfc6265Cookie)55 TEST(CookieIndicesTest, NonRfc6265Cookie) {
56   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
57                      .AddHeader(kCookieIndicesHeader, R"("text/html")")
58                      .Build();
59   auto result = ParseCookieIndices(*headers);
60   EXPECT_THAT(result, Optional(ElementsAre()));
61 }
62 
TEST(CookieIndicesTest,NotAList)63 TEST(CookieIndicesTest, NotAList) {
64   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
65                      .AddHeader(kCookieIndicesHeader, ",,,")
66                      .Build();
67   auto result = ParseCookieIndices(*headers);
68   EXPECT_FALSE(result.has_value());
69 }
70 
TEST(CookieIndicesTest,InnerList)71 TEST(CookieIndicesTest, InnerList) {
72   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
73                      .AddHeader(kCookieIndicesHeader, R"(("foo"))")
74                      .Build();
75   auto result = ParseCookieIndices(*headers);
76   EXPECT_FALSE(result.has_value());
77 }
78 
TEST(CookieIndicesTest,Token)79 TEST(CookieIndicesTest, Token) {
80   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
81                      .AddHeader(kCookieIndicesHeader, R"(alpha)")
82                      .Build();
83   auto result = ParseCookieIndices(*headers);
84   EXPECT_FALSE(result.has_value());
85 }
86 
TEST(CookieIndicesTest,StringWithUnrecognizedParam)87 TEST(CookieIndicesTest, StringWithUnrecognizedParam) {
88   auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
89                      .AddHeader(kCookieIndicesHeader, R"("session"; secure)")
90                      .Build();
91   auto result = ParseCookieIndices(*headers);
92   EXPECT_THAT(result, Optional(ElementsAre("session")));
93 }
94 
TEST(CookieIndicesTest,HashIgnoresCookieOrder)95 TEST(CookieIndicesTest, HashIgnoresCookieOrder) {
96   const std::string cookie_indices[] = {"fruit", "vegetable"};
97   EXPECT_EQ(HashCookieIndices(cookie_indices,
98                               ParsedRequestCookies{{"fruit", "apple"},
99                                                    {"vegetable", "tomato"}}),
100             HashCookieIndices(cookie_indices,
101                               ParsedRequestCookies{{"vegetable", "tomato"},
102                                                    {"fruit", "apple"}}));
103 }
104 
TEST(CookieIndicesTest,HashCaseSensitive)105 TEST(CookieIndicesTest, HashCaseSensitive) {
106   const std::string cookie_indices[] = {"fruit", "vegetable"};
107   EXPECT_NE(HashCookieIndices(cookie_indices,
108                               ParsedRequestCookies{{"fruit", "apple"},
109                                                    {"vegetable", "tomato"}}),
110             HashCookieIndices(cookie_indices,
111                               ParsedRequestCookies{{"Fruit", "apple"},
112                                                    {"vegetable", "tomato"}}));
113   EXPECT_NE(HashCookieIndices(cookie_indices,
114                               ParsedRequestCookies{{"fruit", "apple"},
115                                                    {"vegetable", "tomato"}}),
116             HashCookieIndices(cookie_indices,
117                               ParsedRequestCookies{{"fruit", "Apple"},
118                                                    {"vegetable", "tomato"}}));
119 }
120 
TEST(CookieIndicesTest,HashNotJustConcatenated)121 TEST(CookieIndicesTest, HashNotJustConcatenated) {
122   // Any other simple delimiter would also be bad, but this is the most likely
123   // case to result by accident.
124   const std::string cookie_indices[] = {"fruit", "vegetable"};
125   EXPECT_NE(HashCookieIndices(cookie_indices,
126                               ParsedRequestCookies{{"fruit", "apple"},
127                                                    {"vegetable", "tomato"}}),
128             HashCookieIndices(cookie_indices,
129                               ParsedRequestCookies{{"fruit", "app"},
130                                                    {"vegetable", "letomato"}}));
131 }
132 
TEST(CookieIndicesTest,HashDisregardsOtherCookies)133 TEST(CookieIndicesTest, HashDisregardsOtherCookies) {
134   const std::string cookie_indices[] = {"fruit"};
135   EXPECT_EQ(HashCookieIndices(cookie_indices,
136                               ParsedRequestCookies{{"fruit", "apple"},
137                                                    {"vegetable", "tomato"}}),
138             HashCookieIndices(cookie_indices,
139                               ParsedRequestCookies{{"bread", "pumpernickel"},
140                                                    {"fruit", "apple"}}));
141 }
142 
TEST(CookieIndicesTest,HashDistinguishesEmptyAndAbsentCookies)143 TEST(CookieIndicesTest, HashDistinguishesEmptyAndAbsentCookies) {
144   const std::string cookie_indices[] = {"fruit"};
145   EXPECT_NE(
146       HashCookieIndices(cookie_indices, ParsedRequestCookies{{"fruit", ""}}),
147       HashCookieIndices(cookie_indices, ParsedRequestCookies{}));
148 }
149 
TEST(CookieIndicesTest,IgnoresOrderOfDuplicateCookies)150 TEST(CookieIndicesTest, IgnoresOrderOfDuplicateCookies) {
151   const std::string cookie_indices[] = {"fruit"};
152   EXPECT_EQ(HashCookieIndices(
153                 cookie_indices,
154                 ParsedRequestCookies{{"fruit", "lime"}, {"fruit", "pear"}}),
155             HashCookieIndices(
156                 cookie_indices,
157                 ParsedRequestCookies{{"fruit", "pear"}, {"fruit", "lime"}}));
158 }
159 
160 }  // namespace
161 }  // namespace net
162