LibDevTools: Pass request initiator type to network panel
Propagate the request initiator type (e.g., "xmlhttprequest", "fetch", "script", "stylesheet") from LibWeb through the IPC layer to DevTools. This enables Firefox DevTools to correctly identify XHR/fetch requests and display appropriate cause types in the Network panel's "Initiator" column.
This commit is contained in:
parent
31ffd2e8e5
commit
681d00c218
15 changed files with 50 additions and 20 deletions
|
|
@ -343,7 +343,7 @@ void FrameActor::on_console_message(WebView::ConsoleOutput console_output)
|
|||
void FrameActor::on_network_request_started(DevToolsDelegate::NetworkRequestData data)
|
||||
{
|
||||
auto& actor = devtools().register_actor<NetworkEventActor>(data.request_id);
|
||||
actor.set_request_info(move(data.url), move(data.method), data.start_time, move(data.request_headers), move(data.request_body));
|
||||
actor.set_request_info(move(data.url), move(data.method), data.start_time, move(data.request_headers), move(data.request_body), move(data.initiator_type));
|
||||
m_network_events.set(data.request_id, actor);
|
||||
|
||||
JsonArray events;
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@ NetworkEventActor::NetworkEventActor(DevToolsServer& devtools, String name, u64
|
|||
|
||||
NetworkEventActor::~NetworkEventActor() = default;
|
||||
|
||||
void NetworkEventActor::set_request_info(String url, String method, UnixDateTime start_time, Vector<HTTP::Header> request_headers, ByteBuffer request_body)
|
||||
void NetworkEventActor::set_request_info(String url, String method, UnixDateTime start_time, Vector<HTTP::Header> request_headers, ByteBuffer request_body, Optional<String> initiator_type)
|
||||
{
|
||||
m_url = move(url);
|
||||
m_method = move(method);
|
||||
m_start_time = start_time;
|
||||
m_request_headers = move(request_headers);
|
||||
m_request_body = move(request_body);
|
||||
m_initiator_type = move(initiator_type);
|
||||
}
|
||||
|
||||
void NetworkEventActor::set_response_start(u32 status_code, Optional<String> reason_phrase)
|
||||
|
|
@ -68,9 +69,26 @@ void NetworkEventActor::set_request_complete(u64 body_size, Requests::RequestTim
|
|||
|
||||
JsonObject NetworkEventActor::serialize_initial_event() const
|
||||
{
|
||||
// FIXME: Detect actual cause type (xhr, fetch, script, stylesheet, image, etc.)
|
||||
// Determine if this is an XHR/fetch request (Firefox groups both under "XHR" filter)
|
||||
bool is_xhr = m_initiator_type.has_value()
|
||||
&& (m_initiator_type.value() == "xmlhttprequest"sv || m_initiator_type.value() == "fetch"sv);
|
||||
|
||||
// Map initiator type to Firefox DevTools cause type
|
||||
StringView cause_type = "document"sv;
|
||||
if (m_initiator_type.has_value()) {
|
||||
auto const& type = m_initiator_type.value();
|
||||
if (type == "xmlhttprequest"sv)
|
||||
cause_type = "xhr"sv;
|
||||
else if (type == "css"sv)
|
||||
cause_type = "stylesheet"sv;
|
||||
else if (type == "img"sv || type == "image"sv)
|
||||
cause_type = "image"sv;
|
||||
else
|
||||
cause_type = type;
|
||||
}
|
||||
|
||||
JsonObject cause;
|
||||
cause.set("type"sv, "document"sv);
|
||||
cause.set("type"sv, cause_type);
|
||||
|
||||
JsonObject event;
|
||||
event.set("resourceType"sv, "network-event"sv);
|
||||
|
|
@ -80,8 +98,7 @@ JsonObject NetworkEventActor::serialize_initial_event() const
|
|||
event.set("timeStamp"sv, m_start_time.milliseconds_since_epoch());
|
||||
event.set("url"sv, m_url);
|
||||
event.set("method"sv, m_method);
|
||||
// FIXME: Detect if request is XHR/fetch
|
||||
event.set("isXHR"sv, false);
|
||||
event.set("isXHR"sv, is_xhr);
|
||||
event.set("cause"sv, move(cause));
|
||||
event.set("private"sv, false);
|
||||
// FIXME: Detect if response is from cache
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
u64 request_id() const { return m_request_id; }
|
||||
|
||||
void set_request_info(String url, String method, UnixDateTime start_time, Vector<HTTP::Header> request_headers, ByteBuffer request_body);
|
||||
void set_request_info(String url, String method, UnixDateTime start_time, Vector<HTTP::Header> request_headers, ByteBuffer request_body, Optional<String> initiator_type);
|
||||
void set_response_start(u32 status_code, Optional<String> reason_phrase);
|
||||
void set_response_headers(Vector<HTTP::Header> response_headers);
|
||||
void append_response_body(ByteBuffer data);
|
||||
|
|
@ -53,6 +53,7 @@ private:
|
|||
UnixDateTime m_start_time;
|
||||
Vector<HTTP::Header> m_request_headers;
|
||||
ByteBuffer m_request_body;
|
||||
Optional<String> m_initiator_type;
|
||||
|
||||
Optional<u32> m_status_code;
|
||||
Optional<String> m_reason_phrase;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ public:
|
|||
UnixDateTime start_time;
|
||||
Vector<HTTP::Header> request_headers;
|
||||
ByteBuffer request_body;
|
||||
Optional<String> initiator_type;
|
||||
};
|
||||
|
||||
struct NetworkResponseData {
|
||||
|
|
|
|||
|
|
@ -2085,6 +2085,7 @@ GC::Ref<PendingResponse> nonstandard_resource_loader_file_or_http_network_fetch(
|
|||
load_request.set_page(page);
|
||||
load_request.set_method(request->method());
|
||||
load_request.set_store_set_cookie_headers(include_credentials == IncludeCredentials::Yes);
|
||||
load_request.set_initiator_type(request->initiator_type());
|
||||
|
||||
if (auto const* body = request->body().get_pointer<GC::Ref<Infrastructure::Body>>()) {
|
||||
(*body)->source().visit(
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <LibHTTP/HeaderList.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/Export.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
|
|
@ -36,6 +37,9 @@ public:
|
|||
bool store_set_cookie_headers() const { return m_store_set_cookie_headers; }
|
||||
void set_store_set_cookie_headers(bool store_set_cookie_headers) { m_store_set_cookie_headers = store_set_cookie_headers; }
|
||||
|
||||
Optional<Fetch::Infrastructure::Request::InitiatorType> const& initiator_type() const { return m_initiator_type; }
|
||||
void set_initiator_type(Optional<Fetch::Infrastructure::Request::InitiatorType> initiator_type) { m_initiator_type = move(initiator_type); }
|
||||
|
||||
void start_timer() { m_load_timer.start(); }
|
||||
AK::Duration load_time() const { return m_load_timer.elapsed_time(); }
|
||||
|
||||
|
|
@ -52,6 +56,7 @@ private:
|
|||
Core::ElapsedTimer m_load_timer;
|
||||
GC::Root<Page> m_page;
|
||||
bool m_store_set_cookie_headers { true };
|
||||
Optional<Fetch::Infrastructure::Request::InitiatorType> m_initiator_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <LibURL/Parser.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/URL.h>
|
||||
#include <LibWeb/Loader/ContentFilter.h>
|
||||
#include <LibWeb/Loader/GeneratedPagesLoader.h>
|
||||
|
|
@ -473,8 +474,12 @@ RefPtr<Requests::Request> ResourceLoader::start_network_request(LoadRequest cons
|
|||
return {};
|
||||
};
|
||||
|
||||
if (auto page = request.page())
|
||||
page->client().page_did_start_network_request(protocol_request->id(), request.url().value(), request.method(), request.headers().headers(), request.body());
|
||||
if (auto page = request.page()) {
|
||||
Optional<String> initiator_type_string;
|
||||
if (request.initiator_type().has_value())
|
||||
initiator_type_string = Fetch::Infrastructure::initiator_type_to_string(request.initiator_type().value()).to_string();
|
||||
page->client().page_did_start_network_request(protocol_request->id(), request.url().value(), request.method(), request.headers().headers(), request.body(), move(initiator_type_string));
|
||||
}
|
||||
|
||||
++m_pending_loads;
|
||||
if (on_load_counter_change)
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ public:
|
|||
|
||||
virtual void page_did_change_audio_play_state(HTML::AudioPlayState) { }
|
||||
|
||||
virtual void page_did_start_network_request([[maybe_unused]] u64 request_id, [[maybe_unused]] URL::URL const& url, [[maybe_unused]] ByteString const& method, [[maybe_unused]] Vector<HTTP::Header> const& request_headers, [[maybe_unused]] ReadonlyBytes request_body) { }
|
||||
virtual void page_did_start_network_request([[maybe_unused]] u64 request_id, [[maybe_unused]] URL::URL const& url, [[maybe_unused]] ByteString const& method, [[maybe_unused]] Vector<HTTP::Header> const& request_headers, [[maybe_unused]] ReadonlyBytes request_body, [[maybe_unused]] Optional<String> initiator_type) { }
|
||||
virtual void page_did_receive_network_response_headers([[maybe_unused]] u64 request_id, [[maybe_unused]] u32 status_code, [[maybe_unused]] Optional<String> reason_phrase, [[maybe_unused]] Vector<HTTP::Header> const& response_headers) { }
|
||||
virtual void page_did_receive_network_response_body([[maybe_unused]] u64 request_id, [[maybe_unused]] ReadonlyBytes data) { }
|
||||
virtual void page_did_finish_network_request([[maybe_unused]] u64 request_id, [[maybe_unused]] u64 body_size, [[maybe_unused]] Requests::RequestTimingInfo const& timing_info, [[maybe_unused]] Optional<Requests::NetworkError> const& network_error) { }
|
||||
|
|
|
|||
|
|
@ -1301,8 +1301,8 @@ void Application::listen_for_network_events(DevTools::TabDescription const& desc
|
|||
if (!view.has_value())
|
||||
return;
|
||||
|
||||
view->on_network_request_started = [on_request_started = move(on_request_started)](u64 request_id, URL::URL const& url, ByteString const& method, Vector<HTTP::Header> const& headers, ByteBuffer request_body) {
|
||||
on_request_started({ request_id, url.to_string(), MUST(String::from_byte_string(method)), UnixDateTime::now(), headers, move(request_body) });
|
||||
view->on_network_request_started = [on_request_started = move(on_request_started)](u64 request_id, URL::URL const& url, ByteString const& method, Vector<HTTP::Header> const& headers, ByteBuffer request_body, Optional<String> initiator_type) {
|
||||
on_request_started({ request_id, url.to_string(), MUST(String::from_byte_string(method)), UnixDateTime::now(), headers, move(request_body), move(initiator_type) });
|
||||
};
|
||||
|
||||
view->on_network_response_headers_received = [on_response_headers = move(on_response_headers)](u64 request_id, u32 status_code, Optional<String> const& reason_phrase, Vector<HTTP::Header> const& headers) {
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public:
|
|||
Function<void(Web::CSS::StyleSheetIdentifier const&, URL::URL const&, String const&)> on_received_style_sheet_source;
|
||||
Function<void(JsonValue)> on_received_js_console_result;
|
||||
Function<void(ConsoleOutput)> on_console_message;
|
||||
Function<void(u64 request_id, URL::URL const&, ByteString const&, Vector<HTTP::Header> const&, ByteBuffer)> on_network_request_started;
|
||||
Function<void(u64 request_id, URL::URL const&, ByteString const&, Vector<HTTP::Header> const&, ByteBuffer, Optional<String>)> on_network_request_started;
|
||||
Function<void(u64 request_id, u32 status_code, Optional<String> const&, Vector<HTTP::Header> const&)> on_network_response_headers_received;
|
||||
Function<void(u64 request_id, ByteBuffer)> on_network_response_body_received;
|
||||
Function<void(u64 request_id, u64 body_size, Requests::RequestTimingInfo const&, Optional<Requests::NetworkError> const&)> on_network_request_finished;
|
||||
|
|
|
|||
|
|
@ -436,11 +436,11 @@ void WebContentClient::did_output_js_console_message(u64 page_id, ConsoleOutput
|
|||
}
|
||||
}
|
||||
|
||||
void WebContentClient::did_start_network_request(u64 page_id, u64 request_id, URL::URL url, ByteString method, Vector<HTTP::Header> request_headers, ByteBuffer request_body)
|
||||
void WebContentClient::did_start_network_request(u64 page_id, u64 request_id, URL::URL url, ByteString method, Vector<HTTP::Header> request_headers, ByteBuffer request_body, Optional<String> initiator_type)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value()) {
|
||||
if (view->on_network_request_started)
|
||||
view->on_network_request_started(request_id, url, method, request_headers, move(request_body));
|
||||
view->on_network_request_started(request_id, url, method, request_headers, move(request_body), move(initiator_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ private:
|
|||
virtual void did_get_internal_page_info(u64 page_id, PageInfoType, String) override;
|
||||
virtual void did_execute_js_console_input(u64 page_id, JsonValue) override;
|
||||
virtual void did_output_js_console_message(u64 page_id, ConsoleOutput) override;
|
||||
virtual void did_start_network_request(u64 page_id, u64 request_id, URL::URL, ByteString method, Vector<HTTP::Header>, ByteBuffer request_body) override;
|
||||
virtual void did_start_network_request(u64 page_id, u64 request_id, URL::URL, ByteString method, Vector<HTTP::Header>, ByteBuffer request_body, Optional<String> initiator_type) override;
|
||||
virtual void did_receive_network_response_headers(u64 page_id, u64 request_id, u32 status_code, Optional<String> reason_phrase, Vector<HTTP::Header>) override;
|
||||
virtual void did_receive_network_response_body(u64 page_id, u64 request_id, ByteBuffer data) override;
|
||||
virtual void did_finish_network_request(u64 page_id, u64 request_id, u64 body_size, Requests::RequestTimingInfo, Optional<Requests::NetworkError>) override;
|
||||
|
|
|
|||
|
|
@ -751,9 +751,9 @@ void PageClient::received_message_from_web_ui(String const& name, JS::Value data
|
|||
m_web_ui->received_message_from_web_ui(name, data);
|
||||
}
|
||||
|
||||
void PageClient::page_did_start_network_request(u64 request_id, URL::URL const& url, ByteString const& method, Vector<HTTP::Header> const& request_headers, ReadonlyBytes request_body)
|
||||
void PageClient::page_did_start_network_request(u64 request_id, URL::URL const& url, ByteString const& method, Vector<HTTP::Header> const& request_headers, ReadonlyBytes request_body, Optional<String> initiator_type)
|
||||
{
|
||||
client().async_did_start_network_request(m_id, request_id, url, method, request_headers, request_body);
|
||||
client().async_did_start_network_request(m_id, request_id, url, method, request_headers, request_body, move(initiator_type));
|
||||
}
|
||||
|
||||
void PageClient::page_did_receive_network_response_headers(u64 request_id, u32 status_code, Optional<String> reason_phrase, Vector<HTTP::Header> const& response_headers)
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ private:
|
|||
virtual void page_did_paint(Gfx::IntRect const& content_rect, i32 bitmap_id) override;
|
||||
virtual void page_did_take_screenshot(Gfx::ShareableBitmap const& screenshot) override;
|
||||
virtual void received_message_from_web_ui(String const& name, JS::Value data) override;
|
||||
virtual void page_did_start_network_request(u64 request_id, URL::URL const&, ByteString const&, Vector<HTTP::Header> const&, ReadonlyBytes) override;
|
||||
virtual void page_did_start_network_request(u64 request_id, URL::URL const&, ByteString const&, Vector<HTTP::Header> const&, ReadonlyBytes, Optional<String>) override;
|
||||
virtual void page_did_receive_network_response_headers(u64 request_id, u32 status_code, Optional<String>, Vector<HTTP::Header> const&) override;
|
||||
virtual void page_did_receive_network_response_body(u64 request_id, ReadonlyBytes) override;
|
||||
virtual void page_did_finish_network_request(u64 request_id, u64 body_size, Requests::RequestTimingInfo const&, Optional<Requests::NetworkError> const&) override;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ endpoint WebContentClient
|
|||
did_execute_js_console_input(u64 page_id, JsonValue result) =|
|
||||
did_output_js_console_message(u64 page_id, WebView::ConsoleOutput console_output) =|
|
||||
|
||||
did_start_network_request(u64 page_id, u64 request_id, URL::URL url, ByteString method, Vector<HTTP::Header> request_headers, ByteBuffer request_body) =|
|
||||
did_start_network_request(u64 page_id, u64 request_id, URL::URL url, ByteString method, Vector<HTTP::Header> request_headers, ByteBuffer request_body, Optional<String> initiator_type) =|
|
||||
did_receive_network_response_headers(u64 page_id, u64 request_id, u32 status_code, Optional<String> reason_phrase, Vector<HTTP::Header> response_headers) =|
|
||||
did_receive_network_response_body(u64 page_id, u64 request_id, ByteBuffer data) =|
|
||||
did_finish_network_request(u64 page_id, u64 request_id, u64 body_size, Requests::RequestTimingInfo timing_info, Optional<Requests::NetworkError> network_error) =|
|
||||
|
|
|
|||
Loading…
Reference in a new issue