CookieJar.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Function.h>
  8. #include <AK/HashMap.h>
  9. #include <AK/Optional.h>
  10. #include <AK/String.h>
  11. #include <AK/StringView.h>
  12. #include <AK/Traits.h>
  13. #include <LibCore/DateTime.h>
  14. #include <LibSQL/Type.h>
  15. #include <LibURL/Forward.h>
  16. #include <LibWeb/Cookie/Cookie.h>
  17. #include <LibWeb/Forward.h>
  18. #include <LibWebView/Forward.h>
  19. namespace WebView {
  20. struct CookieStorageKey {
  21. bool operator==(CookieStorageKey const&) const = default;
  22. String name;
  23. String domain;
  24. String path;
  25. };
  26. class CookieJar {
  27. struct Statements {
  28. SQL::StatementID create_table { 0 };
  29. SQL::StatementID insert_cookie { 0 };
  30. SQL::StatementID update_cookie { 0 };
  31. SQL::StatementID update_cookie_last_access_time { 0 };
  32. SQL::StatementID expire_cookie { 0 };
  33. SQL::StatementID select_cookie { 0 };
  34. SQL::StatementID select_all_cookies { 0 };
  35. };
  36. struct PersistedStorage {
  37. Database& database;
  38. Statements statements;
  39. };
  40. using TransientStorage = HashMap<CookieStorageKey, Web::Cookie::Cookie>;
  41. public:
  42. static ErrorOr<CookieJar> create(Database&);
  43. static CookieJar create();
  44. String get_cookie(const URL::URL& url, Web::Cookie::Source source);
  45. void set_cookie(const URL::URL& url, Web::Cookie::ParsedCookie const& parsed_cookie, Web::Cookie::Source source);
  46. void update_cookie(Web::Cookie::Cookie);
  47. void dump_cookies();
  48. Vector<Web::Cookie::Cookie> get_all_cookies();
  49. Vector<Web::Cookie::Cookie> get_all_cookies(URL::URL const& url);
  50. Optional<Web::Cookie::Cookie> get_named_cookie(URL::URL const& url, StringView name);
  51. private:
  52. explicit CookieJar(PersistedStorage);
  53. explicit CookieJar(TransientStorage);
  54. static Optional<String> canonicalize_domain(const URL::URL& url);
  55. static bool domain_matches(StringView string, StringView domain_string);
  56. static bool path_matches(StringView request_path, StringView cookie_path);
  57. static String default_path(const URL::URL& url);
  58. enum class MatchingCookiesSpecMode {
  59. RFC6265,
  60. WebDriver,
  61. };
  62. void store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, const URL::URL& url, String canonicalized_domain, Web::Cookie::Source source);
  63. Vector<Web::Cookie::Cookie> get_matching_cookies(const URL::URL& url, StringView canonicalized_domain, Web::Cookie::Source source, MatchingCookiesSpecMode mode = MatchingCookiesSpecMode::RFC6265);
  64. void insert_cookie_into_database(Web::Cookie::Cookie const& cookie);
  65. void update_cookie_in_database(Web::Cookie::Cookie const& cookie);
  66. void update_cookie_last_access_time_in_database(Web::Cookie::Cookie const& cookie);
  67. using OnCookieFound = Function<void(Web::Cookie::Cookie&, Web::Cookie::Cookie)>;
  68. using OnCookieNotFound = Function<void(Web::Cookie::Cookie)>;
  69. void select_cookie_from_database(Web::Cookie::Cookie cookie, OnCookieFound on_result, OnCookieNotFound on_complete_without_results);
  70. using OnSelectAllCookiesResult = Function<void(Web::Cookie::Cookie)>;
  71. void select_all_cookies_from_database(OnSelectAllCookiesResult on_result);
  72. void purge_expired_cookies();
  73. Variant<PersistedStorage, TransientStorage> m_storage;
  74. };
  75. }
  76. template<>
  77. struct AK::Traits<WebView::CookieStorageKey> : public AK::DefaultTraits<WebView::CookieStorageKey> {
  78. static unsigned hash(WebView::CookieStorageKey const& key)
  79. {
  80. unsigned hash = 0;
  81. hash = pair_int_hash(hash, key.name.hash());
  82. hash = pair_int_hash(hash, key.domain.hash());
  83. hash = pair_int_hash(hash, key.path.hash());
  84. return hash;
  85. }
  86. };