123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- // Copyright 2015 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <string>
- #include <utility>
- #include "base/bind.h"
- #include "base/memory/weak_ptr.h"
- #include "base/run_loop.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "net/base/isolation_info.h"
- #include "net/cookies/canonical_cookie.h"
- #include "net/cookies/canonical_cookie_test_helpers.h"
- #include "net/cookies/cookie_access_result.h"
- #include "net/cookies/cookie_store.h"
- #include "net/cookies/cookie_util.h"
- #include "net/http/http_request_headers.h"
- #include "net/socket/socket_test_util.h"
- #include "net/websockets/websocket_stream_create_test_base.h"
- #include "net/websockets/websocket_test_util.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "url/gurl.h"
- #include "url/origin.h"
- namespace net {
- namespace {
- using ::testing::TestWithParam;
- using ::testing::ValuesIn;
- const WebSocketExtraHeaders kNoCookieHeader = {};
- class TestBase : public WebSocketStreamCreateTestBase {
- public:
- void CreateAndConnect(const GURL& url,
- const url::Origin& origin,
- const SiteForCookies& site_for_cookies,
- const IsolationInfo& isolation_info,
- const WebSocketExtraHeaders& cookie_header,
- const std::string& response_body) {
- url_request_context_host_.SetExpectations(
- WebSocketStandardRequestWithCookies(
- url.path(), url.host(), origin, cookie_header,
- /*send_additional_request_headers=*/{}, /*extra_headers=*/{}),
- response_body);
- CreateAndConnectStream(url, NoSubProtocols(), origin, site_for_cookies,
- isolation_info, HttpRequestHeaders(), nullptr);
- }
- };
- struct ClientUseCookieParameter {
- // The URL for the WebSocket connection.
- const char* const url;
- // The URL for the previously set cookies.
- const char* const cookie_url;
- // The previously set cookies contents.
- const char* const cookie_line;
- // The Cookie: HTTP header expected to appear in the WS request.
- const WebSocketExtraHeaders cookie_header;
- };
- class WebSocketStreamClientUseCookieTest
- : public TestBase,
- public TestWithParam<ClientUseCookieParameter> {
- public:
- ~WebSocketStreamClientUseCookieTest() override {
- // Permit any endpoint locks to be released.
- stream_request_.reset();
- stream_.reset();
- base::RunLoop().RunUntilIdle();
- }
- static void SetCookieHelperFunction(const base::RepeatingClosure& task,
- base::WeakPtr<bool> weak_is_called,
- base::WeakPtr<bool> weak_result,
- CookieAccessResult access_result) {
- *weak_is_called = true;
- *weak_result = access_result.status.IsInclude();
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
- }
- };
- struct ServerSetCookieParameter {
- // The URL for the WebSocket connection.
- const char* const url;
- // The URL used to query cookies after the response received.
- const char* const cookie_url;
- // The cookies expected to appear for |cookie_url| inquiry.
- const char* const cookie_line;
- // The Set-Cookie: HTTP header attached to the response.
- const WebSocketExtraHeaders cookie_header;
- };
- class WebSocketStreamServerSetCookieTest
- : public TestBase,
- public TestWithParam<ServerSetCookieParameter> {
- public:
- ~WebSocketStreamServerSetCookieTest() override {
- // Permit any endpoint locks to be released.
- stream_request_.reset();
- stream_.reset();
- base::RunLoop().RunUntilIdle();
- }
- static void GetCookieListHelperFunction(
- base::OnceClosure task,
- base::WeakPtr<bool> weak_is_called,
- base::WeakPtr<CookieList> weak_result,
- const CookieAccessResultList& cookie_list,
- const CookieAccessResultList& excluded_cookies) {
- *weak_is_called = true;
- *weak_result = cookie_util::StripAccessResults(cookie_list);
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task));
- }
- };
- TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
- // For wss tests.
- url_request_context_host_.AddSSLSocketDataProvider(
- std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
- CookieStore* store =
- url_request_context_host_.GetURLRequestContext()->cookie_store();
- const GURL url(GetParam().url);
- const GURL cookie_url(GetParam().cookie_url);
- const url::Origin origin = url::Origin::Create(GURL(GetParam().url));
- const SiteForCookies site_for_cookies = SiteForCookies::FromOrigin(origin);
- const IsolationInfo isolation_info =
- IsolationInfo::Create(IsolationInfo::RequestType::kOther, origin, origin,
- SiteForCookies::FromOrigin(origin));
- const std::string cookie_line(GetParam().cookie_line);
- bool is_called = false;
- bool set_cookie_result = false;
- base::WeakPtrFactory<bool> weak_is_called(&is_called);
- base::WeakPtrFactory<bool> weak_set_cookie_result(&set_cookie_result);
- base::RunLoop run_loop;
- auto cookie =
- CanonicalCookie::Create(cookie_url, cookie_line, base::Time::Now(),
- absl::nullopt /* server_time */,
- absl::nullopt /* cookie_partition_key */);
- store->SetCanonicalCookieAsync(
- std::move(cookie), cookie_url, net::CookieOptions::MakeAllInclusive(),
- base::BindOnce(&SetCookieHelperFunction, run_loop.QuitClosure(),
- weak_is_called.GetWeakPtr(),
- weak_set_cookie_result.GetWeakPtr()));
- run_loop.Run();
- ASSERT_TRUE(is_called);
- ASSERT_TRUE(set_cookie_result);
- CreateAndConnect(url, origin, site_for_cookies, isolation_info,
- GetParam().cookie_header, WebSocketStandardResponse(""));
- WaitUntilConnectDone();
- EXPECT_FALSE(has_failed());
- }
- TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) {
- // For wss tests.
- url_request_context_host_.AddSSLSocketDataProvider(
- std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
- const GURL url(GetParam().url);
- const GURL cookie_url(GetParam().cookie_url);
- const url::Origin origin = url::Origin::Create(GURL(GetParam().url));
- const SiteForCookies site_for_cookies = SiteForCookies::FromOrigin(origin);
- const IsolationInfo isolation_info =
- IsolationInfo::Create(IsolationInfo::RequestType::kOther, origin, origin,
- SiteForCookies::FromOrigin(origin));
- const std::string cookie_line(GetParam().cookie_line);
- HttpRequestHeaders headers;
- for (const auto& [key, value] : GetParam().cookie_header)
- headers.SetHeader(key, value);
- std::string cookie_header(headers.ToString());
- const std::string response = base::StringPrintf(
- "HTTP/1.1 101 Switching Protocols\r\n"
- "Upgrade: websocket\r\n"
- "Connection: Upgrade\r\n"
- "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
- "%s",
- cookie_header.c_str());
- CookieStore* store =
- url_request_context_host_.GetURLRequestContext()->cookie_store();
- CreateAndConnect(url, origin, site_for_cookies, isolation_info,
- /*cookie_header=*/{}, response);
- WaitUntilConnectDone();
- EXPECT_FALSE(has_failed()) << failure_message();
- bool is_called = false;
- CookieList get_cookie_list_result;
- base::WeakPtrFactory<bool> weak_is_called(&is_called);
- base::WeakPtrFactory<CookieList> weak_get_cookie_list_result(
- &get_cookie_list_result);
- base::RunLoop run_loop;
- store->GetCookieListWithOptionsAsync(
- cookie_url, net::CookieOptions::MakeAllInclusive(),
- CookiePartitionKeyCollection(),
- base::BindOnce(&GetCookieListHelperFunction, run_loop.QuitClosure(),
- weak_is_called.GetWeakPtr(),
- weak_get_cookie_list_result.GetWeakPtr()));
- run_loop.Run();
- EXPECT_TRUE(is_called);
- EXPECT_THAT(get_cookie_list_result, MatchesCookieLine(cookie_line));
- }
- // Test parameters definitions follow...
- const ClientUseCookieParameter kClientUseCookieParameters[] = {
- // Non-secure cookies for ws
- {"ws://www.example.com",
- "http://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "https://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "ws://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "wss://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- // Non-secure cookies for wss
- {"wss://www.example.com",
- "http://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "https://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "ws://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "wss://www.example.com",
- "test-cookie",
- {{"Cookie", "test-cookie"}}},
- // Secure-cookies for ws
- {"ws://www.example.com", "https://www.example.com", "test-cookie; secure",
- kNoCookieHeader},
- {"ws://www.example.com", "wss://www.example.com", "test-cookie; secure",
- kNoCookieHeader},
- // Secure-cookies for wss
- {"wss://www.example.com",
- "https://www.example.com",
- "test-cookie; secure",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "wss://www.example.com",
- "test-cookie; secure",
- {{"Cookie", "test-cookie"}}},
- // Non-secure cookies for ws (sharing domain)
- {"ws://www.example.com",
- "http://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "https://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "ws://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "wss://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- // Non-secure cookies for wss (sharing domain)
- {"wss://www.example.com",
- "http://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "https://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "ws://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "wss://www2.example.com",
- "test-cookie; Domain=example.com",
- {{"Cookie", "test-cookie"}}},
- // Secure-cookies for ws (sharing domain)
- {"ws://www.example.com", "https://www2.example.com",
- "test-cookie; Domain=example.com; secure", kNoCookieHeader},
- {"ws://www.example.com", "wss://www2.example.com",
- "test-cookie; Domain=example.com; secure", kNoCookieHeader},
- // Secure-cookies for wss (sharing domain)
- {"wss://www.example.com",
- "https://www2.example.com",
- "test-cookie; Domain=example.com; secure",
- {{"Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "wss://www2.example.com",
- "test-cookie; Domain=example.com; secure",
- {{"Cookie", "test-cookie"}}},
- // Non-matching cookies for ws
- {"ws://www.example.com", "http://www2.example.com", "test-cookie",
- kNoCookieHeader},
- {"ws://www.example.com", "https://www2.example.com", "test-cookie",
- kNoCookieHeader},
- {"ws://www.example.com", "ws://www2.example.com", "test-cookie",
- kNoCookieHeader},
- {"ws://www.example.com", "wss://www2.example.com", "test-cookie",
- kNoCookieHeader},
- // Non-matching cookies for wss
- {"wss://www.example.com", "http://www2.example.com", "test-cookie",
- kNoCookieHeader},
- {"wss://www.example.com", "https://www2.example.com", "test-cookie",
- kNoCookieHeader},
- {"wss://www.example.com", "ws://www2.example.com", "test-cookie",
- kNoCookieHeader},
- {"wss://www.example.com", "wss://www2.example.com", "test-cookie",
- kNoCookieHeader},
- };
- INSTANTIATE_TEST_SUITE_P(WebSocketStreamClientUseCookieTest,
- WebSocketStreamClientUseCookieTest,
- ValuesIn(kClientUseCookieParameters));
- const ServerSetCookieParameter kServerSetCookieParameters[] = {
- // Cookies coming from ws
- {"ws://www.example.com",
- "http://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "https://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "ws://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "wss://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- // Cookies coming from wss
- {"wss://www.example.com",
- "http://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "https://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "ws://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "wss://www.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie"}}},
- // cookies coming from ws (sharing domain)
- {"ws://www.example.com",
- "http://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- {"ws://www.example.com",
- "https://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- {"ws://www.example.com",
- "ws://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- {"ws://www.example.com",
- "wss://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- // cookies coming from wss (sharing domain)
- {"wss://www.example.com",
- "http://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- {"wss://www.example.com",
- "https://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- {"wss://www.example.com",
- "ws://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- {"wss://www.example.com",
- "wss://www2.example.com",
- "test-cookie",
- {{"Set-Cookie", "test-cookie; Domain=example.com"}}},
- // Non-matching cookies coming from ws
- {"ws://www.example.com",
- "http://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "https://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "ws://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- {"ws://www.example.com",
- "wss://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- // Non-matching cookies coming from wss
- {"wss://www.example.com",
- "http://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "https://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "ws://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- {"wss://www.example.com",
- "wss://www2.example.com",
- "",
- {{"Set-Cookie", "test-cookie"}}},
- };
- INSTANTIATE_TEST_SUITE_P(WebSocketStreamServerSetCookieTest,
- WebSocketStreamServerSetCookieTest,
- ValuesIn(kServerSetCookieParameters));
- } // namespace
- } // namespace net
|