Files
electron/patches/chromium/feat_expose_raw_response_headers_from_urlloader.patch
2022-09-13 09:36:58 -07:00

159 lines
8.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Tue, 17 Aug 2021 22:42:42 -0700
Subject: feat: expose raw response headers from URLLoader
With https://chromium-review.googlesource.com/c/chromium/src/+/2856099
unfiltered response headers are only available via trusted channel
through //services/network/public/mojom/devtools_observer.mojom.
https://github.com/electron/electron/pull/30503/commits/28f4da1582d046e96cb58f3cbb590503e89dfd0d
was an attempt to use this interface but given the original response is
signalled on a different interface via URLLoaderClient::OnReceiveResponse
it is harder to sync these data from two different channels for a synchronous
event emitted on the SimpleURLLoaderWrapper::OnResponseStarted.
This patch does the minimal approach to add back the raw response
headers, moving forward we should find a way in upstream to provide
access to these headers for loader clients created on the browser process.
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index 7e02d8c952d2228a39d1fd1fa5a36859e2ea9ab9..1cfa83a0d0d0fa3fec3f92faa94aece678f83552 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -234,6 +234,7 @@ bool ResourceRequest::EqualsForTesting(const ResourceRequest& request) const {
do_not_prompt_for_login == request.do_not_prompt_for_login &&
is_outermost_main_frame == request.is_outermost_main_frame &&
transition_type == request.transition_type &&
+ report_raw_headers == request.report_raw_headers &&
previews_state == request.previews_state &&
upgrade_if_insecure == request.upgrade_if_insecure &&
is_revalidating == request.is_revalidating &&
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index 10d7912016a57e413e7f6056697028bbc5a4e0e6..f22a212ca8dc3f95373e23d22689c896720b7ee0 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -159,6 +159,7 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ResourceRequest {
bool do_not_prompt_for_login = false;
bool is_outermost_main_frame = false;
int transition_type = 0;
+ bool report_raw_headers = false;
int previews_state = 0;
bool upgrade_if_insecure = false;
bool is_revalidating = false;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index 10295a165e2131b7cd5bff996f36f2214db7a125..2d1bb21bf5813125397a93d368de031b11bb4bbb 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -209,6 +209,7 @@ bool StructTraits<
out->do_not_prompt_for_login = data.do_not_prompt_for_login();
out->is_outermost_main_frame = data.is_outermost_main_frame();
out->transition_type = data.transition_type();
+ out->report_raw_headers = data.report_raw_headers();
out->previews_state = data.previews_state();
out->upgrade_if_insecure = data.upgrade_if_insecure();
out->is_revalidating = data.is_revalidating();
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index b4f785570ffab62087ef9be3d18cecb6c747fa38..f6ff5ebc9808e230ed358203c5d0024c676bcd85 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -269,6 +269,9 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
static int32_t transition_type(const network::ResourceRequest& request) {
return request.transition_type;
}
+ static bool report_raw_headers(const network::ResourceRequest& request) {
+ return request.report_raw_headers;
+ }
static int32_t previews_state(const network::ResourceRequest& request) {
return request.previews_state;
}
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom
index 05cc03e830d2805d6d572a38e2606de0f346b6bd..75b8da2f1141dffa34d01e84e339b791fdd60664 100644
--- a/services/network/public/mojom/url_request.mojom
+++ b/services/network/public/mojom/url_request.mojom
@@ -312,6 +312,9 @@ struct URLRequest {
// about this.
int32 transition_type;
+ // Whether to provide unfiltered response headers.
+ bool report_raw_headers;
+
// Whether or not to request a Preview version of the resource or let the
// browser decide.
// Note: this is an enum of type PreviewsState.
diff --git a/services/network/public/mojom/url_response_head.mojom b/services/network/public/mojom/url_response_head.mojom
index 3d2bcc3e81eb42f645fa4e8b1425cb5c54cfd3a1..4cdbe0e38609abfd0b0b5856deb8b2dd5c91ead8 100644
--- a/services/network/public/mojom/url_response_head.mojom
+++ b/services/network/public/mojom/url_response_head.mojom
@@ -8,6 +8,7 @@ import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/fetch_api.mojom";
import "services/network/public/mojom/ip_address_space.mojom";
+import "services/network/public/mojom/http_raw_headers.mojom";
import "services/network/public/mojom/ip_endpoint.mojom";
import "services/network/public/mojom/load_timing_info.mojom";
import "services/network/public/mojom/network_param.mojom";
@@ -28,6 +29,9 @@ struct URLResponseHead {
// The response headers or NULL if the URL type does not support headers.
HttpResponseHeaders headers;
+ // Actual response headers, as obtained from the network stack.
+ array<HttpRawHeaderPair> raw_response_headers;
+
// The mime type of the response. This may be a derived value.
string mime_type;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc
index 2e8a874bf93e03e7c194dc13555eead6fe1fcafa..5b28db971f8feebd36965ccafe8b1b957b3f1ede 100644
--- a/services/network/url_loader.cc
+++ b/services/network/url_loader.cc
@@ -606,6 +606,7 @@ URLLoader::URLLoader(
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
base::SequencedTaskRunnerHandle::Get()),
per_factory_corb_state_(context.GetMutableCorbState()),
+ report_raw_headers_(request.report_raw_headers),
devtools_request_id_(request.devtools_request_id),
request_mode_(request.mode),
request_credentials_mode_(request.credentials_mode),
@@ -795,7 +796,7 @@ URLLoader::URLLoader(
url_request_->SetRequestHeadersCallback(base::BindRepeating(
&URLLoader::SetRawRequestHeadersAndNotify, base::Unretained(this)));
- if (devtools_request_id()) {
+ if (devtools_request_id() || report_raw_headers_) {
url_request_->SetResponseHeadersCallback(base::BindRepeating(
&URLLoader::SetRawResponseHeaders, base::Unretained(this)));
}
@@ -1555,6 +1556,19 @@ void URLLoader::OnResponseStarted(net::URLRequest* url_request, int net_error) {
}
response_ = BuildResponseHead();
+ if (raw_response_headers_ && report_raw_headers_) {
+ std::vector<network::mojom::HttpRawHeaderPairPtr> header_array;
+ size_t iterator = 0;
+ std::string name, value;
+ while (raw_response_headers_->EnumerateHeaderLines(&iterator, &name, &value)) {
+ network::mojom::HttpRawHeaderPairPtr pair =
+ network::mojom::HttpRawHeaderPair::New();
+ pair->key = name;
+ pair->value = value;
+ header_array.push_back(std::move(pair));
+ }
+ response_->raw_response_headers = std::move(header_array);
+ }
DispatchOnRawResponse();
// Parse and remove the Trust Tokens response headers, if any are expected,
diff --git a/services/network/url_loader.h b/services/network/url_loader.h
index 7a1d7fe570c3b3d94d1dbcfdda2b965323ce5e95..9bc4eb1a1f300529308a2f120b4bc676b11acfbe 100644
--- a/services/network/url_loader.h
+++ b/services/network/url_loader.h
@@ -518,6 +518,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
std::unique_ptr<ResourceScheduler::ScheduledResourceRequest>
resource_scheduler_request_handle_;
+ // Whether client requested raw headers.
+ bool report_raw_headers_ = false;
bool enable_reporting_raw_headers_ = false;
bool seen_raw_request_headers_ = false;
scoped_refptr<const net::HttpResponseHeaders> raw_response_headers_;