/* * Copyright (c) 2021-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace WebView { struct CookieStorageKey { bool operator==(CookieStorageKey const&) const = default; String name; String domain; String path; }; class CookieJar { struct Statements { SQL::StatementID create_table { 0 }; SQL::StatementID insert_cookie { 0 }; SQL::StatementID update_cookie { 0 }; SQL::StatementID update_cookie_last_access_time { 0 }; SQL::StatementID expire_cookie { 0 }; SQL::StatementID select_cookie { 0 }; SQL::StatementID select_all_cookies { 0 }; }; struct PersistedStorage { Database& database; Statements statements; }; using TransientStorage = HashMap; public: static ErrorOr create(Database&); static CookieJar create(); 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(Web::Cookie::Cookie); void dump_cookies(); Vector get_all_cookies(); Vector get_all_cookies(URL const& url); Optional get_named_cookie(URL const& url, StringView name); private: explicit CookieJar(PersistedStorage); explicit CookieJar(TransientStorage); static Optional canonicalize_domain(const URL& url); static bool domain_matches(StringView string, StringView domain_string); static bool path_matches(StringView request_path, StringView cookie_path); static String default_path(const URL& url); enum class MatchingCookiesSpecMode { RFC6265, WebDriver, }; void store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, const URL& url, String canonicalized_domain, Web::Cookie::Source source); Vector get_matching_cookies(const URL& url, StringView canonicalized_domain, Web::Cookie::Source source, MatchingCookiesSpecMode mode = MatchingCookiesSpecMode::RFC6265); void insert_cookie_into_database(Web::Cookie::Cookie const& cookie); void update_cookie_in_database(Web::Cookie::Cookie const& cookie); void update_cookie_last_access_time_in_database(Web::Cookie::Cookie const& cookie); using OnCookieFound = Function; using OnCookieNotFound = Function; void select_cookie_from_database(Web::Cookie::Cookie cookie, OnCookieFound on_result, OnCookieNotFound on_complete_without_results); using OnSelectAllCookiesResult = Function; void select_all_cookies_from_database(OnSelectAllCookiesResult on_result); void purge_expired_cookies(); Variant m_storage; }; } template<> struct AK::Traits : public AK::DefaultTraits { static unsigned hash(WebView::CookieStorageKey const& key) { unsigned hash = 0; hash = pair_int_hash(hash, key.name.hash()); hash = pair_int_hash(hash, key.domain.hash()); hash = pair_int_hash(hash, key.path.hash()); return hash; } };