From 30360918d4c2a1f5de7e34e4e89f4c320e268c18 Mon Sep 17 00:00:00 2001 From: Tobias Christiansen Date: Sun, 16 Oct 2022 19:48:19 +0200 Subject: [PATCH] Browser: Allow changing of existing Cookies in the CookieJar And attach all the plumbing through to Tab over BrowserWindow. --- .../Applications/Browser/BrowserWindow.cpp | 4 +++ Userland/Applications/Browser/CookieJar.cpp | 29 +++++++++++++++++++ Userland/Applications/Browser/CookieJar.h | 1 + Userland/Applications/Browser/Tab.h | 1 + 4 files changed, 35 insertions(+) diff --git a/Userland/Applications/Browser/BrowserWindow.cpp b/Userland/Applications/Browser/BrowserWindow.cpp index a1cfe695b2..60757e6ee5 100644 --- a/Userland/Applications/Browser/BrowserWindow.cpp +++ b/Userland/Applications/Browser/BrowserWindow.cpp @@ -566,6 +566,10 @@ void BrowserWindow::create_new_tab(URL url, bool activate) m_cookie_jar.dump_cookies(); }; + new_tab.on_update_cookie = [this](auto const& url, auto cookie) { + m_cookie_jar.update_cookie(url, move(cookie)); + }; + new_tab.on_get_cookies_entries = [this]() { return m_cookie_jar.get_all_cookies(); }; diff --git a/Userland/Applications/Browser/CookieJar.cpp b/Userland/Applications/Browser/CookieJar.cpp index 2c3b27d805..d2f2500529 100644 --- a/Userland/Applications/Browser/CookieJar.cpp +++ b/Userland/Applications/Browser/CookieJar.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Tim Flynn * Copyright (c) 2022, the SerenityOS developers. + * Copyright (c) 2022, Tobias Christiansen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -48,6 +49,34 @@ void CookieJar::set_cookie(const URL& url, Web::Cookie::ParsedCookie const& pars purge_expired_cookies(); } +// This is based on https://www.rfc-editor.org/rfc/rfc6265#section-5.3 as store_cookie() below +// however the whole ParsedCookie->Cookie conversion is skipped. +void CookieJar::update_cookie(URL const& url, Web::Cookie::Cookie cookie) +{ + auto domain = canonicalize_domain(url); + if (!domain.has_value()) + return; + + // 6. If the canonicalized request-host does not domain-match the domain-attribute: Ignore the cookie entirely and abort these steps. + if (!domain_matches(domain.value(), cookie.domain)) + return; + + // 11. If the cookie store contains a cookie with the same name, domain, and path as the newly created cookie: + CookieStorageKey key { cookie.name, cookie.domain, cookie.path }; + + if (auto old_cookie = m_cookies.find(key); old_cookie != m_cookies.end()) { + // Update the creation-time of the newly created cookie to match the creation-time of the old-cookie. + cookie.creation_time = old_cookie->value.creation_time; + // Remove the old-cookie from the cookie store. + m_cookies.remove(old_cookie); + } + + // 12. Insert the newly created cookie into the cookie store. + m_cookies.set(key, move(cookie)); + + purge_expired_cookies(); +} + void CookieJar::dump_cookies() const { constexpr auto key_color = "\033[34;1m"sv; diff --git a/Userland/Applications/Browser/CookieJar.h b/Userland/Applications/Browser/CookieJar.h index 3aedeceef4..7bae12c04f 100644 --- a/Userland/Applications/Browser/CookieJar.h +++ b/Userland/Applications/Browser/CookieJar.h @@ -28,6 +28,7 @@ class CookieJar { public: String get_cookie(const URL& url, Web::Cookie::Source source); void set_cookie(const URL& url, Web::Cookie::ParsedCookie const& parsed_cookie, Web::Cookie::Source source); + void update_cookie(URL const&, Web::Cookie::Cookie); void dump_cookies() const; Vector get_all_cookies() const; diff --git a/Userland/Applications/Browser/Tab.h b/Userland/Applications/Browser/Tab.h index 0d3515925b..7d176c455a 100644 --- a/Userland/Applications/Browser/Tab.h +++ b/Userland/Applications/Browser/Tab.h @@ -64,6 +64,7 @@ public: Function on_get_cookie; Function on_set_cookie; Function on_dump_cookies; + Function on_update_cookie; Function()> on_get_cookies_entries; Function()> on_get_local_storage_entries; Function()> on_get_session_storage_entries;