diff options
author | Luke Wilde <lukew@serenityos.org> | 2022-12-30 22:57:58 +0000 |
---|---|---|
committer | Tim Flynn <trflynn89@pm.me> | 2022-12-30 21:56:54 -0500 |
commit | 6d188d72c0cbcd04df6b3bb5fe3c7b56d7fcd8ef (patch) | |
tree | 5b02ec5819107e83cd4ab88349ac0d54593972bb | |
parent | c9d434247dffe85ec69b05dbc57ffe17a64959c7 (diff) | |
download | serenity-6d188d72c0cbcd04df6b3bb5fe3c7b56d7fcd8ef.zip |
LibWeb: Store cookies for every HTTP response
As per Fetch, we are supposed to store cookies from Set-Cookie as soon
as we receive response headers for any HTTP response, even in error
cases.
Required by Twitter to login, as it sets cookies via XHR.
-rw-r--r-- | Userland/Libraries/LibWeb/Loader/FrameLoader.cpp | 24 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Loader/FrameLoader.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp | 26 |
3 files changed, 25 insertions, 27 deletions
diff --git a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp index 8c0f8de912..377a4f875e 100644 --- a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp @@ -12,7 +12,6 @@ #include <LibGfx/ImageDecoder.h> #include <LibMarkdown/Document.h> #include <LibWeb/Bindings/MainThreadVM.h> -#include <LibWeb/Cookie/ParsedCookie.h> #include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/ElementFactory.h> #include <LibWeb/DOM/Text.h> @@ -363,33 +362,10 @@ void FrameLoader::load_favicon(RefPtr<Gfx::Bitmap> bitmap) } } -void FrameLoader::store_response_cookies(AK::URL const& url, DeprecatedString const& cookies) -{ - auto* page = browsing_context().page(); - if (!page) - return; - - auto set_cookie_json_value = MUST(JsonValue::from_string(cookies)); - VERIFY(set_cookie_json_value.type() == JsonValue::Type::Array); - - for (auto const& set_cookie_entry : set_cookie_json_value.as_array().values()) { - VERIFY(set_cookie_entry.type() == JsonValue::Type::String); - - auto cookie = Cookie::parse_cookie(set_cookie_entry.as_string()); - if (!cookie.has_value()) - continue; - - page->client().page_did_set_cookie(url, cookie.value(), Cookie::Source::Http); // FIXME: Determine cookie source correctly - } -} - void FrameLoader::resource_did_load() { auto url = resource()->url(); - if (auto set_cookie = resource()->response_headers().get("Set-Cookie"); set_cookie.has_value()) - store_response_cookies(url, *set_cookie); - // For 3xx (Redirection) responses, the Location value refers to the preferred target resource for automatically redirecting the request. auto status_code = resource()->status_code(); if (status_code.has_value() && *status_code >= 300 && *status_code <= 399) { diff --git a/Userland/Libraries/LibWeb/Loader/FrameLoader.h b/Userland/Libraries/LibWeb/Loader/FrameLoader.h index 5183e29754..06840cd876 100644 --- a/Userland/Libraries/LibWeb/Loader/FrameLoader.h +++ b/Userland/Libraries/LibWeb/Loader/FrameLoader.h @@ -47,8 +47,6 @@ private: void load_favicon(RefPtr<Gfx::Bitmap> bitmap = nullptr); bool parse_document(DOM::Document&, ByteBuffer const& data); - void store_response_cookies(AK::URL const& url, DeprecatedString const& cookies); - HTML::BrowsingContext& m_browsing_context; size_t m_redirects_count { 0 }; }; diff --git a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp index 475b3930bb..981ed0b1d4 100644 --- a/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ResourceLoader.cpp @@ -10,6 +10,8 @@ #include <AK/JsonObject.h> #include <LibCore/ElapsedTimer.h> #include <LibCore/File.h> +#include <LibWeb/Cookie/Cookie.h> +#include <LibWeb/Cookie/ParsedCookie.h> #include <LibWeb/Loader/ContentFilter.h> #include <LibWeb/Loader/LoadRequest.h> #include <LibWeb/Loader/ProxyMappings.h> @@ -136,6 +138,22 @@ static void emit_signpost(DeprecatedString const& message, int id) #endif } +static void store_response_cookies(Page& page, AK::URL const& url, DeprecatedString const& cookies) +{ + auto set_cookie_json_value = MUST(JsonValue::from_string(cookies)); + VERIFY(set_cookie_json_value.type() == JsonValue::Type::Array); + + for (auto const& set_cookie_entry : set_cookie_json_value.as_array().values()) { + VERIFY(set_cookie_entry.type() == JsonValue::Type::String); + + auto cookie = Cookie::parse_cookie(set_cookie_entry.as_string()); + if (!cookie.has_value()) + continue; + + page.client().page_did_set_cookie(url, cookie.value(), Cookie::Source::Http); // FIXME: Determine cookie source correctly + } +} + static size_t resource_id = 0; void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, HashMap<DeprecatedString, DeprecatedString, CaseInsensitiveStringTraits> const& response_headers, Optional<u32> status_code)> success_callback, Function<void(DeprecatedString const&, Optional<u32> status_code)> error_callback, Optional<u32> timeout, Function<void()> timeout_callback) @@ -295,10 +313,16 @@ void ResourceLoader::load(LoadRequest& request, Function<void(ReadonlyBytes, Has m_active_requests.set(*protocol_request); - protocol_request->on_buffered_request_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback), log_success, log_failure, request, &protocol_request = *protocol_request](bool success, auto, auto& response_headers, auto status_code, ReadonlyBytes payload) { + protocol_request->on_buffered_request_finish = [this, success_callback = move(success_callback), error_callback = move(error_callback), log_success, log_failure, request, &protocol_request = *protocol_request](bool success, auto, auto& response_headers, auto status_code, ReadonlyBytes payload) mutable { --m_pending_loads; if (on_load_counter_change) on_load_counter_change(); + + if (request.page().has_value()) { + if (auto set_cookie = response_headers.get("Set-Cookie"); set_cookie.has_value()) + store_response_cookies(request.page().value(), request.url(), *set_cookie); + } + if (!success || (status_code.has_value() && *status_code >= 400 && *status_code <= 599)) { StringBuilder error_builder; if (status_code.has_value()) |