2021-04-11 14:43:54 +00:00
|
|
|
/*
|
2024-01-26 15:47:57 +00:00
|
|
|
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
|
2021-04-11 14:43:54 +00:00
|
|
|
*
|
2021-04-22 08:24:48 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2021-04-11 14:43:54 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-10-27 16:56:22 +00:00
|
|
|
#include <AK/Function.h>
|
2021-04-11 14:43:54 +00:00
|
|
|
#include <AK/HashMap.h>
|
|
|
|
#include <AK/Optional.h>
|
2024-01-26 16:39:00 +00:00
|
|
|
#include <AK/String.h>
|
2024-01-26 15:47:57 +00:00
|
|
|
#include <AK/StringView.h>
|
2023-04-20 18:22:40 +00:00
|
|
|
#include <AK/Traits.h>
|
2021-04-12 03:40:49 +00:00
|
|
|
#include <LibCore/DateTime.h>
|
2024-05-01 00:05:56 +00:00
|
|
|
#include <LibCore/Timer.h>
|
2024-03-18 03:22:27 +00:00
|
|
|
#include <LibURL/Forward.h>
|
2021-04-13 21:01:20 +00:00
|
|
|
#include <LibWeb/Cookie/Cookie.h>
|
2021-04-13 20:47:05 +00:00
|
|
|
#include <LibWeb/Forward.h>
|
2024-06-04 20:34:32 +00:00
|
|
|
#include <LibWebView/Database.h>
|
2023-08-31 11:07:07 +00:00
|
|
|
#include <LibWebView/Forward.h>
|
2021-04-11 14:43:54 +00:00
|
|
|
|
2023-08-31 11:07:07 +00:00
|
|
|
namespace WebView {
|
2021-04-11 14:43:54 +00:00
|
|
|
|
2023-04-20 18:22:40 +00:00
|
|
|
struct CookieStorageKey {
|
|
|
|
bool operator==(CookieStorageKey const&) const = default;
|
|
|
|
|
2024-01-26 16:39:00 +00:00
|
|
|
String name;
|
|
|
|
String domain;
|
|
|
|
String path;
|
2023-04-20 18:22:40 +00:00
|
|
|
};
|
|
|
|
|
2021-04-11 14:43:54 +00:00
|
|
|
class CookieJar {
|
2022-10-27 16:56:22 +00:00
|
|
|
struct Statements {
|
2024-06-04 20:34:32 +00:00
|
|
|
Database::StatementID insert_cookie { 0 };
|
|
|
|
Database::StatementID expire_cookie { 0 };
|
|
|
|
Database::StatementID select_all_cookies { 0 };
|
2022-10-27 16:56:22 +00:00
|
|
|
};
|
|
|
|
|
2024-05-01 00:05:56 +00:00
|
|
|
class TransientStorage {
|
|
|
|
public:
|
|
|
|
using Cookies = HashMap<CookieStorageKey, Web::Cookie::Cookie>;
|
|
|
|
|
|
|
|
void set_cookies(Cookies);
|
|
|
|
void set_cookie(CookieStorageKey, Web::Cookie::Cookie);
|
|
|
|
Optional<Web::Cookie::Cookie> get_cookie(CookieStorageKey const&);
|
|
|
|
|
|
|
|
size_t size() const { return m_cookies.size(); }
|
|
|
|
|
|
|
|
UnixDateTime purge_expired_cookies();
|
|
|
|
|
2024-06-04 20:34:32 +00:00
|
|
|
auto take_dirty_cookies() { return move(m_dirty_cookies); }
|
2024-05-01 00:05:56 +00:00
|
|
|
|
|
|
|
template<typename Callback>
|
|
|
|
void for_each_cookie(Callback callback)
|
|
|
|
{
|
|
|
|
for (auto& it : m_cookies)
|
|
|
|
callback(it.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Cookies m_cookies;
|
2024-06-04 20:34:32 +00:00
|
|
|
Cookies m_dirty_cookies;
|
2024-05-01 00:05:56 +00:00
|
|
|
};
|
|
|
|
|
2023-04-20 18:22:40 +00:00
|
|
|
struct PersistedStorage {
|
2024-05-01 00:05:56 +00:00
|
|
|
void insert_cookie(Web::Cookie::Cookie const& cookie);
|
|
|
|
TransientStorage::Cookies select_all_cookies();
|
|
|
|
|
2023-04-20 18:22:40 +00:00
|
|
|
Database& database;
|
|
|
|
Statements statements;
|
2024-05-01 00:05:56 +00:00
|
|
|
RefPtr<Core::Timer> synchronization_timer {};
|
2023-04-20 18:22:40 +00:00
|
|
|
};
|
|
|
|
|
2021-04-11 14:43:54 +00:00
|
|
|
public:
|
2024-05-01 00:05:56 +00:00
|
|
|
static ErrorOr<NonnullOwnPtr<CookieJar>> create(Database&);
|
|
|
|
static NonnullOwnPtr<CookieJar> create();
|
|
|
|
|
|
|
|
~CookieJar();
|
2022-10-27 16:56:22 +00:00
|
|
|
|
2024-03-18 03:22:27 +00:00
|
|
|
String get_cookie(const URL::URL& url, Web::Cookie::Source source);
|
|
|
|
void set_cookie(const URL::URL& url, Web::Cookie::ParsedCookie const& parsed_cookie, Web::Cookie::Source source);
|
2022-11-28 16:24:04 +00:00
|
|
|
void update_cookie(Web::Cookie::Cookie);
|
2022-10-27 16:56:22 +00:00
|
|
|
void dump_cookies();
|
|
|
|
Vector<Web::Cookie::Cookie> get_all_cookies();
|
2024-03-18 03:22:27 +00:00
|
|
|
Vector<Web::Cookie::Cookie> get_all_cookies(URL::URL const& url);
|
|
|
|
Optional<Web::Cookie::Cookie> get_named_cookie(URL::URL const& url, StringView name);
|
2021-04-11 14:43:54 +00:00
|
|
|
|
|
|
|
private:
|
2024-05-01 00:05:56 +00:00
|
|
|
explicit CookieJar(Optional<PersistedStorage>);
|
|
|
|
|
|
|
|
AK_MAKE_NONCOPYABLE(CookieJar);
|
|
|
|
AK_MAKE_NONMOVABLE(CookieJar);
|
2022-10-27 16:56:22 +00:00
|
|
|
|
2024-03-18 03:22:27 +00:00
|
|
|
static Optional<String> canonicalize_domain(const URL::URL& url);
|
2024-01-26 15:47:57 +00:00
|
|
|
static bool domain_matches(StringView string, StringView domain_string);
|
|
|
|
static bool path_matches(StringView request_path, StringView cookie_path);
|
2024-03-18 03:22:27 +00:00
|
|
|
static String default_path(const URL::URL& url);
|
2021-04-13 03:16:27 +00:00
|
|
|
|
2022-11-11 14:24:07 +00:00
|
|
|
enum class MatchingCookiesSpecMode {
|
|
|
|
RFC6265,
|
|
|
|
WebDriver,
|
|
|
|
};
|
|
|
|
|
2024-03-18 03:22:27 +00:00
|
|
|
void store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, const URL::URL& url, String canonicalized_domain, Web::Cookie::Source source);
|
|
|
|
Vector<Web::Cookie::Cookie> get_matching_cookies(const URL::URL& url, StringView canonicalized_domain, Web::Cookie::Source source, MatchingCookiesSpecMode mode = MatchingCookiesSpecMode::RFC6265);
|
2021-04-13 03:16:27 +00:00
|
|
|
|
2024-05-01 00:05:56 +00:00
|
|
|
Optional<PersistedStorage> m_persisted_storage;
|
|
|
|
TransientStorage m_transient_storage;
|
2021-04-11 14:43:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
2023-04-20 18:22:40 +00:00
|
|
|
|
|
|
|
template<>
|
2023-11-08 19:29:12 +00:00
|
|
|
struct AK::Traits<WebView::CookieStorageKey> : public AK::DefaultTraits<WebView::CookieStorageKey> {
|
2023-08-31 11:07:07 +00:00
|
|
|
static unsigned hash(WebView::CookieStorageKey const& key)
|
2023-04-20 18:22:40 +00:00
|
|
|
{
|
|
|
|
unsigned hash = 0;
|
2024-01-26 16:39:00 +00:00
|
|
|
hash = pair_int_hash(hash, key.name.hash());
|
|
|
|
hash = pair_int_hash(hash, key.domain.hash());
|
|
|
|
hash = pair_int_hash(hash, key.path.hash());
|
2023-04-20 18:22:40 +00:00
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
};
|