Skip to content

Commit

Permalink
LibRequests+LibWeb: Propagate HTTP reason phrase
Browse files Browse the repository at this point in the history
  • Loading branch information
rmg-x committed Oct 30, 2024
1 parent 12b1469 commit 7b5c90c
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 42 deletions.
8 changes: 5 additions & 3 deletions Userland/Libraries/LibRequests/Request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,10 @@ void Request::set_buffered_request_finished_callback(BufferedRequestFinished on_

m_internal_buffered_data = make<InternalBufferedData>();

on_headers_received = [this](auto& headers, auto response_code) {
on_headers_received = [this](auto& headers, auto response_code, auto const& reason_phrase) {
m_internal_buffered_data->response_headers = headers;
m_internal_buffered_data->response_code = move(response_code);
m_internal_buffered_data->reason_phrase = reason_phrase;
};

on_finish = [this, on_buffered_request_finished = move(on_buffered_request_finished)](auto total_size, auto network_error) {
Expand All @@ -61,6 +62,7 @@ void Request::set_buffered_request_finished_callback(BufferedRequestFinished on_
network_error,
m_internal_buffered_data->response_headers,
m_internal_buffered_data->response_code,
m_internal_buffered_data->reason_phrase,
output_buffer);
};

Expand All @@ -87,10 +89,10 @@ void Request::did_finish(Badge<RequestClient>, u64 total_size, Optional<NetworkE
on_finish(total_size, network_error);
}

void Request::did_receive_headers(Badge<RequestClient>, HTTP::HeaderMap const& response_headers, Optional<u32> response_code)
void Request::did_receive_headers(Badge<RequestClient>, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> const& reason_phrase)
{
if (on_headers_received)
on_headers_received(response_headers, response_code);
on_headers_received(response_headers, response_code, reason_phrase);
}

void Request::did_request_certificates(Badge<RequestClient>)
Expand Down
7 changes: 4 additions & 3 deletions Userland/Libraries/LibRequests/Request.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class Request : public RefCounted<Request> {
int fd() const { return m_fd; }
bool stop();

using BufferedRequestFinished = Function<void(u64 total_size, Optional<NetworkError> const& network_error, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, ReadonlyBytes payload)>;
using BufferedRequestFinished = Function<void(u64 total_size, Optional<NetworkError> const& network_error, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> reason_phrase, ReadonlyBytes payload)>;

// Configure the request such that the entirety of the response data is buffered. The callback receives that data and
// the response headers all at once. Using this method is mutually exclusive with `set_unbuffered_data_received_callback`.
void set_buffered_request_finished_callback(BufferedRequestFinished);

using HeadersReceived = Function<void(HTTP::HeaderMap const& response_headers, Optional<u32> response_code)>;
using HeadersReceived = Function<void(HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> const& reason_phrase)>;
using DataReceived = Function<void(ReadonlyBytes data)>;
using RequestFinished = Function<void(u64 total_size, Optional<NetworkError> network_error)>;

Expand All @@ -55,7 +55,7 @@ class Request : public RefCounted<Request> {
Function<CertificateAndKey()> on_certificate_requested;

void did_finish(Badge<RequestClient>, u64 total_size, Optional<NetworkError> const& network_error);
void did_receive_headers(Badge<RequestClient>, HTTP::HeaderMap const& response_headers, Optional<u32> response_code);
void did_receive_headers(Badge<RequestClient>, HTTP::HeaderMap const& response_headers, Optional<u32> response_code, Optional<String> const& reason_phrase);
void did_request_certificates(Badge<RequestClient>);

RefPtr<Core::Notifier>& write_notifier(Badge<RequestClient>) { return m_write_notifier; }
Expand Down Expand Up @@ -85,6 +85,7 @@ class Request : public RefCounted<Request> {
AllocatingMemoryStream payload_stream;
HTTP::HeaderMap response_headers;
Optional<u32> response_code;
Optional<String> reason_phrase;
};

struct InternalStreamData {
Expand Down
4 changes: 2 additions & 2 deletions Userland/Libraries/LibRequests/RequestClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ void RequestClient::request_finished(i32 request_id, u64 total_size, Optional<Ne
m_requests.remove(request_id);
}

void RequestClient::headers_became_available(i32 request_id, HTTP::HeaderMap const& response_headers, Optional<u32> const& status_code)
void RequestClient::headers_became_available(i32 request_id, HTTP::HeaderMap const& response_headers, Optional<u32> const& status_code, Optional<String> const& reason_phrase)
{
auto request = const_cast<Request*>(m_requests.get(request_id).value_or(nullptr));
if (!request) {
warnln("Received headers for non-existent request {}", request_id);
return;
}
request->did_receive_headers({}, response_headers, status_code);
request->did_receive_headers({}, response_headers, status_code, reason_phrase);
}

void RequestClient::certificate_requested(i32 request_id)
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibRequests/RequestClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class RequestClient final
virtual void request_started(i32, IPC::File const&) override;
virtual void request_finished(i32, u64, Optional<NetworkError> const&) override;
virtual void certificate_requested(i32) override;
virtual void headers_became_available(i32, HTTP::HeaderMap const&, Optional<u32> const&) override;
virtual void headers_became_available(i32, HTTP::HeaderMap const&, Optional<u32> const&, Optional<String> const&) override;

virtual void websocket_connected(i64 websocket_id) override;
virtual void websocket_received(i64 websocket_id, bool, ByteBuffer const&) override;
Expand Down
19 changes: 13 additions & 6 deletions Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2260,7 +2260,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
// 13. Set up stream with byte reading support with pullAlgorithm set to pullAlgorithm, cancelAlgorithm set to cancelAlgorithm.
Streams::set_up_readable_stream_controller_with_byte_reading_support(stream, pull_algorithm, cancel_algorithm);

auto on_headers_received = JS::create_heap_function(vm.heap(), [&vm, request, pending_response, stream](HTTP::HeaderMap const& response_headers, Optional<u32> status_code) {
auto on_headers_received = JS::create_heap_function(vm.heap(), [&vm, request, pending_response, stream](HTTP::HeaderMap const& response_headers, Optional<u32> status_code, Optional<String> const& reason_phrase) {
(void)request;
if (pending_response->is_resolved()) {
// RequestServer will send us the response headers twice, the second time being for HTTP trailers. This
Expand All @@ -2270,7 +2270,9 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load

auto response = Infrastructure::Response::create(vm);
response->set_status(status_code.value_or(200));
// FIXME: Set response status message

if (reason_phrase.has_value())
response->set_status_message(MUST(ByteBuffer::copy(reason_phrase.value().bytes())));

if constexpr (WEB_FETCH_DEBUG) {
dbgln("Fetch: ResourceLoader load for '{}' {}: (status {})",
Expand Down Expand Up @@ -2337,7 +2339,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load

ResourceLoader::the().load_unbuffered(load_request, on_headers_received, on_data_received, on_complete);
} else {
auto on_load_success = JS::create_heap_function(vm.heap(), [&realm, &vm, request, pending_response](ReadonlyBytes data, HTTP::HeaderMap const& response_headers, Optional<u32> status_code) {
auto on_load_success = JS::create_heap_function(vm.heap(), [&realm, &vm, request, pending_response](ReadonlyBytes data, HTTP::HeaderMap const& response_headers, Optional<u32> status_code, Optional<String> const& reason_phrase) {
(void)request;
dbgln_if(WEB_FETCH_DEBUG, "Fetch: ResourceLoader load for '{}' complete", request->url());
if constexpr (WEB_FETCH_DEBUG)
Expand All @@ -2350,11 +2352,14 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
auto header = Infrastructure::Header::from_string_pair(name, value);
response->header_list()->append(move(header));
}
// FIXME: Set response status message

if (reason_phrase.has_value())
response->set_status_message(MUST(ByteBuffer::copy(reason_phrase.value().bytes())));

pending_response->resolve(response);
});

auto on_load_error = JS::create_heap_function(vm.heap(), [&realm, &vm, request, pending_response](ByteString const& error, Optional<u32> status_code, ReadonlyBytes data, HTTP::HeaderMap const& response_headers) {
auto on_load_error = JS::create_heap_function(vm.heap(), [&realm, &vm, request, pending_response](ByteString const& error, Optional<u32> status_code, Optional<String> const& reason_phrase, ReadonlyBytes data, HTTP::HeaderMap const& response_headers) {
(void)request;
dbgln_if(WEB_FETCH_DEBUG, "Fetch: ResourceLoader load for '{}' failed: {} (status {})", request->url(), error, status_code.value_or(0));
if constexpr (WEB_FETCH_DEBUG)
Expand All @@ -2372,7 +2377,9 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> nonstandard_resource_load
auto header = Infrastructure::Header::from_string_pair(name, value);
response->header_list()->append(move(header));
}
// FIXME: Set response status message

if (reason_phrase.has_value())
response->set_status_message(MUST(ByteBuffer::copy(reason_phrase.value().bytes())));
}
pending_response->resolve(response);
});
Expand Down
Loading

0 comments on commit 7b5c90c

Please sign in to comment.