1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 23:07:35 +00:00

Browser: Add support for CookieJar to run in a transient, in-memory mode

This is to allow running Ladybird without the SQL database for testing.
Primarily, this will let us set 'follow-fork-mode' to 'child' within GDB
to enter the WebContent process, rather than the SQLServer process. But
this is also handy for digging into cookie storage issues.
This commit is contained in:
Timothy Flynn 2023-04-20 14:22:40 -04:00 committed by Andreas Kling
parent 59a1a3f463
commit a01ad58e91
3 changed files with 184 additions and 72 deletions

View file

@ -1,15 +1,17 @@
/*
* Copyright (c) 2021-2022, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include "Forward.h"
#include <AK/DeprecatedString.h>
#include <AK/Function.h>
#include <AK/HashMap.h>
#include <AK/Optional.h>
#include <AK/Traits.h>
#include <LibCore/DateTime.h>
#include <LibSQL/Type.h>
#include <LibWeb/Cookie/Cookie.h>
@ -19,6 +21,14 @@ namespace Browser {
class Database;
struct CookieStorageKey {
bool operator==(CookieStorageKey const&) const = default;
DeprecatedString name;
DeprecatedString domain;
DeprecatedString path;
};
class CookieJar {
struct Statements {
SQL::StatementID create_table { 0 };
@ -29,8 +39,16 @@ class CookieJar {
SQL::StatementID select_all_cookies { 0 };
};
struct PersistedStorage {
Database& database;
Statements statements;
};
using TransientStorage = HashMap<CookieStorageKey, Web::Cookie::Cookie>;
public:
static ErrorOr<CookieJar> create(Database& database);
static ErrorOr<CookieJar> create(Database&);
static CookieJar create();
DeprecatedString 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);
@ -41,7 +59,8 @@ public:
Optional<Web::Cookie::Cookie> get_named_cookie(URL const& url, DeprecatedString const& name);
private:
CookieJar(Database& database, Statements statements);
explicit CookieJar(PersistedStorage);
explicit CookieJar(TransientStorage);
static Optional<DeprecatedString> canonicalize_domain(const URL& url);
static bool domain_matches(DeprecatedString const& string, DeprecatedString const& domain_string);
@ -68,8 +87,19 @@ private:
void purge_expired_cookies();
Database& m_database;
Statements m_statements;
Variant<PersistedStorage, TransientStorage> m_storage;
};
}
template<>
struct AK::Traits<Browser::CookieStorageKey> : public AK::GenericTraits<Browser::CookieStorageKey> {
static unsigned hash(Browser::CookieStorageKey const& key)
{
unsigned hash = 0;
hash = pair_int_hash(hash, string_hash(key.name.characters(), key.name.length()));
hash = pair_int_hash(hash, string_hash(key.domain.characters(), key.domain.length()));
hash = pair_int_hash(hash, string_hash(key.path.characters(), key.path.length()));
return hash;
}
};