blob: 7c8d4b51adf9f0e5c333d60ef78599c2e22a9554 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/http/http_cookie_indices.h"
#include "net/cookies/cookie_util.h"
#include "net/http/http_response_headers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
using cookie_util::ParsedRequestCookies;
using ::testing::ElementsAre;
using ::testing::Optional;
constexpr std::string_view kCookieIndicesHeader = "Cookie-Indices";
TEST(CookieIndicesTest, Absent) {
auto headers =
HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK").Build();
auto result = ParseCookieIndices(*headers);
EXPECT_FALSE(result.has_value());
}
TEST(CookieIndicesTest, PresentButEmpty) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, "")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_THAT(result, Optional(ElementsAre()));
}
TEST(CookieIndicesTest, OneCookie) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, R"("alpha")")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_THAT(result, Optional(ElementsAre("alpha")));
}
TEST(CookieIndicesTest, SeveralCookies) {
auto headers =
HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, R"("alpha", "bravo")")
.AddHeader(kCookieIndicesHeader, R"("charlie", "delta", "echo")")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_THAT(result, Optional(ElementsAre("alpha", "bravo", "charlie", "delta",
"echo")));
}
TEST(CookieIndicesTest, NonRfc6265Cookie) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, R"("text/html")")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_THAT(result, Optional(ElementsAre()));
}
TEST(CookieIndicesTest, NotAList) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, ",,,")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_FALSE(result.has_value());
}
TEST(CookieIndicesTest, InnerList) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, R"(("foo"))")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_FALSE(result.has_value());
}
TEST(CookieIndicesTest, Token) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, R"(alpha)")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_FALSE(result.has_value());
}
TEST(CookieIndicesTest, StringWithUnrecognizedParam) {
auto headers = HttpResponseHeaders::Builder(HttpVersion(1, 1), "200 OK")
.AddHeader(kCookieIndicesHeader, R"("session"; secure)")
.Build();
auto result = ParseCookieIndices(*headers);
EXPECT_THAT(result, Optional(ElementsAre("session")));
}
TEST(CookieIndicesTest, HashIgnoresCookieOrder) {
const std::string cookie_indices[] = {"fruit", "vegetable"};
EXPECT_EQ(HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "apple"},
{"vegetable", "tomato"}}),
HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"vegetable", "tomato"},
{"fruit", "apple"}}));
}
TEST(CookieIndicesTest, HashCaseSensitive) {
const std::string cookie_indices[] = {"fruit", "vegetable"};
EXPECT_NE(HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "apple"},
{"vegetable", "tomato"}}),
HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"Fruit", "apple"},
{"vegetable", "tomato"}}));
EXPECT_NE(HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "apple"},
{"vegetable", "tomato"}}),
HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "Apple"},
{"vegetable", "tomato"}}));
}
TEST(CookieIndicesTest, HashNotJustConcatenated) {
// Any other simple delimiter would also be bad, but this is the most likely
// case to result by accident.
const std::string cookie_indices[] = {"fruit", "vegetable"};
EXPECT_NE(HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "apple"},
{"vegetable", "tomato"}}),
HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "app"},
{"vegetable", "letomato"}}));
}
TEST(CookieIndicesTest, HashDisregardsOtherCookies) {
const std::string cookie_indices[] = {"fruit"};
EXPECT_EQ(HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"fruit", "apple"},
{"vegetable", "tomato"}}),
HashCookieIndices(cookie_indices,
ParsedRequestCookies{{"bread", "pumpernickel"},
{"fruit", "apple"}}));
}
TEST(CookieIndicesTest, HashDistinguishesEmptyAndAbsentCookies) {
const std::string cookie_indices[] = {"fruit"};
EXPECT_NE(
HashCookieIndices(cookie_indices, ParsedRequestCookies{{"fruit", ""}}),
HashCookieIndices(cookie_indices, ParsedRequestCookies{}));
}
TEST(CookieIndicesTest, IgnoresOrderOfDuplicateCookies) {
const std::string cookie_indices[] = {"fruit"};
EXPECT_EQ(HashCookieIndices(
cookie_indices,
ParsedRequestCookies{{"fruit", "lime"}, {"fruit", "pear"}}),
HashCookieIndices(
cookie_indices,
ParsedRequestCookies{{"fruit", "pear"}, {"fruit", "lime"}}));
}
} // namespace
} // namespace net