1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:37:46 +00:00

LibWeb+LibHTTP: Support multiple Set-Cookie response headers

This commit is contained in:
TheFightingCatfish 2021-08-11 06:09:35 +08:00 committed by Ali Mohammad Pur
parent 0e873464ed
commit 57541f433b
3 changed files with 29 additions and 5 deletions

View file

@ -5,6 +5,7 @@
*/ */
#include <AK/Debug.h> #include <AK/Debug.h>
#include <AK/JsonArray.h>
#include <LibCompress/Gzip.h> #include <LibCompress/Gzip.h>
#include <LibCompress/Zlib.h> #include <LibCompress/Zlib.h>
#include <LibCore/Event.h> #include <LibCore/Event.h>
@ -179,8 +180,11 @@ void Job::on_socket_connected()
if (m_state == State::Trailers) { if (m_state == State::Trailers) {
return finish_up(); return finish_up();
} else { } else {
if (on_headers_received) if (on_headers_received) {
if (!m_set_cookie_headers.is_empty())
m_headers.set("Set-Cookie", JsonArray { m_set_cookie_headers }.to_string());
on_headers_received(m_headers, m_code > 0 ? m_code : Optional<u32> {}); on_headers_received(m_headers, m_code > 0 ? m_code : Optional<u32> {});
}
m_state = State::InBody; m_state = State::InBody;
} }
@ -216,7 +220,20 @@ void Job::on_socket_connected()
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); }); return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
} }
auto value = line.substring(name.length() + 2, line.length() - name.length() - 2); auto value = line.substring(name.length() + 2, line.length() - name.length() - 2);
m_headers.set(name, value); if (name.equals_ignoring_case("Set-Cookie")) {
dbgln_if(JOB_DEBUG, "Job: Received Set-Cookie header: '{}'", value);
m_set_cookie_headers.append(move(value));
return;
}
if (auto existing_value = m_headers.get(name); existing_value.has_value()) {
StringBuilder builder;
builder.append(existing_value.value());
builder.append(',');
builder.append(value);
m_headers.set(name, builder.build());
} else {
m_headers.set(name, value);
}
if (name.equals_ignoring_case("Content-Encoding")) { if (name.equals_ignoring_case("Content-Encoding")) {
// Assume that any content-encoding means that we can't decode it as a stream :( // Assume that any content-encoding means that we can't decode it as a stream :(
dbgln_if(JOB_DEBUG, "Content-Encoding {} detected, cannot stream output :(", value); dbgln_if(JOB_DEBUG, "Content-Encoding {} detected, cannot stream output :(", value);

View file

@ -56,6 +56,7 @@ protected:
State m_state { State::InStatus }; State m_state { State::InStatus };
int m_code { -1 }; int m_code { -1 };
HashMap<String, String, CaseInsensitiveStringTraits> m_headers; HashMap<String, String, CaseInsensitiveStringTraits> m_headers;
Vector<String> m_set_cookie_headers;
Vector<ByteBuffer, 2> m_received_buffers; Vector<ByteBuffer, 2> m_received_buffers;
size_t m_buffered_size { 0 }; size_t m_buffered_size { 0 };
size_t m_received_size { 0 }; size_t m_received_size { 0 };

View file

@ -5,6 +5,7 @@
*/ */
#include <AK/Debug.h> #include <AK/Debug.h>
#include <AK/JsonArray.h>
#include <AK/LexicalPath.h> #include <AK/LexicalPath.h>
#include <AK/SourceGenerator.h> #include <AK/SourceGenerator.h>
#include <LibGemini/Document.h> #include <LibGemini/Document.h>
@ -294,10 +295,15 @@ void FrameLoader::resource_did_load()
return; return;
} }
// FIXME: Support multiple instances of the Set-Cookie response header.
auto set_cookie = resource()->response_headers().get("Set-Cookie"); auto set_cookie = resource()->response_headers().get("Set-Cookie");
if (set_cookie.has_value()) if (set_cookie.has_value()) {
document->set_cookie(set_cookie.value(), Cookie::Source::Http); auto set_cookie_json_value = MUST(JsonValue::from_string(set_cookie.value()));
VERIFY(set_cookie_json_value.type() == JsonValue::Type::Array);
for (const auto& set_cookie_entry : set_cookie_json_value.as_array().values()) {
VERIFY(set_cookie_entry.type() == JsonValue::Type::String);
document->set_cookie(set_cookie_entry.as_string(), Cookie::Source::Http);
}
}
if (!url.fragment().is_empty()) if (!url.fragment().is_empty())
browsing_context().scroll_to_anchor(url.fragment()); browsing_context().scroll_to_anchor(url.fragment());