summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/loader
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/loader')
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_bundle.cc68
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_bundle.h7
-rw-r--r--chromium/content/renderer/loader/navigation_response_override_parameters.cc17
-rw-r--r--chromium/content/renderer/loader/navigation_response_override_parameters.h33
-rw-r--r--chromium/content/renderer/loader/request_extra_data.cc2
-rw-r--r--chromium/content/renderer/loader/request_extra_data.h33
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.cc236
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.h37
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher_unittest.cc88
-rw-r--r--chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc1
-rw-r--r--chromium/content/renderer/loader/sync_load_context.cc122
-rw-r--r--chromium/content/renderer/loader/sync_load_context.h14
-rw-r--r--chromium/content/renderer/loader/sync_load_response.h5
-rw-r--r--chromium/content/renderer/loader/test_request_peer.cc3
-rw-r--r--chromium/content/renderer/loader/test_request_peer.h5
-rw-r--r--chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h1
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl.h8
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl_unittest.cc9
-rw-r--r--chromium/content/renderer/loader/url_response_body_consumer_unittest.cc10
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl.cc6
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl.h1
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc40
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.cc139
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.h26
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl_unittest.cc48
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.cc44
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.h14
27 files changed, 683 insertions, 334 deletions
diff --git a/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc b/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
index feb92de61a6..32ddb9deabd 100644
--- a/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
+++ b/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
@@ -24,7 +24,13 @@ class URLLoaderRelay : public network::mojom::URLLoaderClient,
client_sink_(std::move(client_sink)) {}
// network::mojom::URLLoader implementation:
- void FollowRedirect() override { loader_sink_->FollowRedirect(); }
+ void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ DCHECK(!modified_request_headers.has_value())
+ << "Redirect with modified headers was not supported yet. "
+ "crbug.com/845683";
+ loader_sink_->FollowRedirect(base::nullopt);
+ }
void ProceedWithResponse() override { loader_sink_->ProceedWithResponse(); }
@@ -186,32 +192,12 @@ void ChildURLLoaderFactoryBundle::CreateLoaderAndStart(
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
ChildURLLoaderFactoryBundle::Clone() {
- InitDefaultBlobFactoryIfNecessary();
- InitDirectNetworkFactoryIfNecessary();
-
- network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
- if (default_factory_)
- default_factory_->Clone(mojo::MakeRequest(&default_factory_info));
-
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo> factories_info;
- for (auto& factory : factories_) {
- network::mojom::URLLoaderFactoryPtrInfo factory_info;
- factory.second->Clone(mojo::MakeRequest(&factory_info));
- factories_info.emplace(factory.first, std::move(factory_info));
- }
-
- network::mojom::URLLoaderFactoryPtrInfo direct_network_factory_info;
- if (direct_network_factory_) {
- direct_network_factory_->Clone(
- mojo::MakeRequest(&direct_network_factory_info));
- }
-
- // Currently there is no need to override subresources from workers,
- // therefore |subresource_overrides| are not shared with the clones.
+ return CloneInternal(true /* include_default */);
+}
- return std::make_unique<ChildURLLoaderFactoryBundleInfo>(
- std::move(default_factory_info), std::move(factories_info),
- std::move(direct_network_factory_info));
+std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ChildURLLoaderFactoryBundle::CloneWithoutDefaultFactory() {
+ return CloneInternal(false /* include_default */);
}
void ChildURLLoaderFactoryBundle::Update(
@@ -260,6 +246,36 @@ void ChildURLLoaderFactoryBundle::InitDirectNetworkFactoryIfNecessary() {
}
}
+std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ChildURLLoaderFactoryBundle::CloneInternal(bool include_default) {
+ InitDefaultBlobFactoryIfNecessary();
+ InitDirectNetworkFactoryIfNecessary();
+
+ network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
+ if (include_default && default_factory_)
+ default_factory_->Clone(mojo::MakeRequest(&default_factory_info));
+
+ std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo> factories_info;
+ for (auto& factory : factories_) {
+ network::mojom::URLLoaderFactoryPtrInfo factory_info;
+ factory.second->Clone(mojo::MakeRequest(&factory_info));
+ factories_info.emplace(factory.first, std::move(factory_info));
+ }
+
+ network::mojom::URLLoaderFactoryPtrInfo direct_network_factory_info;
+ if (direct_network_factory_) {
+ direct_network_factory_->Clone(
+ mojo::MakeRequest(&direct_network_factory_info));
+ }
+
+ // Currently there is no need to override subresources from workers,
+ // therefore |subresource_overrides| are not shared with the clones.
+
+ return std::make_unique<ChildURLLoaderFactoryBundleInfo>(
+ std::move(default_factory_info), std::move(factories_info),
+ std::move(direct_network_factory_info));
+}
+
std::unique_ptr<ChildURLLoaderFactoryBundleInfo>
ChildURLLoaderFactoryBundle::PassInterface() {
InitDefaultBlobFactoryIfNecessary();
diff --git a/chromium/content/renderer/loader/child_url_loader_factory_bundle.h b/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
index 922cca480bb..cb613cbc247 100644
--- a/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
+++ b/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
@@ -83,6 +83,11 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override;
+ // Returns an info that omits this bundle's default factory, if any. This is
+ // useful to make a clone that bypasses AppCache, for example.
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ CloneWithoutDefaultFactory();
+
std::unique_ptr<ChildURLLoaderFactoryBundleInfo> PassInterface();
void Update(std::unique_ptr<ChildURLLoaderFactoryBundleInfo> info,
@@ -97,6 +102,8 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
private:
void InitDefaultBlobFactoryIfNecessary();
void InitDirectNetworkFactoryIfNecessary();
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> CloneInternal(
+ bool include_default);
PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter_;
PossiblyAssociatedURLLoaderFactoryPtr direct_network_factory_;
diff --git a/chromium/content/renderer/loader/navigation_response_override_parameters.cc b/chromium/content/renderer/loader/navigation_response_override_parameters.cc
new file mode 100644
index 00000000000..91be543f46c
--- /dev/null
+++ b/chromium/content/renderer/loader/navigation_response_override_parameters.cc
@@ -0,0 +1,17 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/loader/navigation_response_override_parameters.h"
+
+#include "base/callback.h"
+
+namespace content {
+
+NavigationResponseOverrideParameters::NavigationResponseOverrideParameters() =
+ default;
+
+NavigationResponseOverrideParameters::~NavigationResponseOverrideParameters() =
+ default;
+
+} // namespace content
diff --git a/chromium/content/renderer/loader/navigation_response_override_parameters.h b/chromium/content/renderer/loader/navigation_response_override_parameters.h
new file mode 100644
index 00000000000..e9a9b7b1d22
--- /dev/null
+++ b/chromium/content/renderer/loader/navigation_response_override_parameters.h
@@ -0,0 +1,33 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_
+#define CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_
+
+#include <vector>
+
+#include "content/common/content_export.h"
+#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "url/gurl.h"
+
+namespace content {
+
+// Used to override parameters of the navigation request.
+struct CONTENT_EXPORT NavigationResponseOverrideParameters {
+ public:
+ NavigationResponseOverrideParameters();
+ ~NavigationResponseOverrideParameters();
+
+ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
+ network::ResourceResponseHead response;
+ std::vector<GURL> redirects;
+ std::vector<network::ResourceResponseHead> redirect_responses;
+ std::vector<net::RedirectInfo> redirect_infos;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_LOADER_NAVIGATION_RESPONSE_OVERRIDE_PARAMETERS_H_
diff --git a/chromium/content/renderer/loader/request_extra_data.cc b/chromium/content/renderer/loader/request_extra_data.cc
index 3b523978f38..de594517dd3 100644
--- a/chromium/content/renderer/loader/request_extra_data.cc
+++ b/chromium/content/renderer/loader/request_extra_data.cc
@@ -17,7 +17,6 @@ RequestExtraData::RequestExtraData()
is_main_frame_(false),
allow_download_(true),
transition_type_(ui::PAGE_TRANSITION_LINK),
- should_replace_current_entry_(false),
service_worker_provider_id_(kInvalidServiceWorkerProviderId),
originated_from_service_worker_(false),
initiated_in_secure_context_(false),
@@ -39,7 +38,6 @@ void RequestExtraData::CopyToResourceRequest(
request->allow_download = allow_download_;
request->transition_type = transition_type_;
- request->should_replace_current_entry = should_replace_current_entry_;
request->service_worker_provider_id = service_worker_provider_id_;
request->originated_from_service_worker = originated_from_service_worker_;
diff --git a/chromium/content/renderer/loader/request_extra_data.h b/chromium/content/renderer/loader/request_extra_data.h
index 8d458507d5e..1c2f0bacdce 100644
--- a/chromium/content/renderer/loader/request_extra_data.h
+++ b/chromium/content/renderer/loader/request_extra_data.h
@@ -12,6 +12,7 @@
#include "content/common/content_export.h"
#include "content/common/navigation_params.h"
#include "content/public/common/url_loader_throttle.h"
+#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/web_url_loader_impl.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -49,10 +50,6 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
void set_transition_type(ui::PageTransition transition_type) {
transition_type_ = transition_type;
}
- void set_should_replace_current_entry(
- bool should_replace_current_entry) {
- should_replace_current_entry_ = should_replace_current_entry;
- }
int service_worker_provider_id() const {
return service_worker_provider_id_;
}
@@ -82,20 +79,20 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
requested_with_ = requested_with;
}
- // PlzNavigate: |stream_override| is used to override certain parameters of
- // navigation requests.
- std::unique_ptr<StreamOverrideParameters> TakeStreamOverrideOwnership() {
- return std::move(stream_override_);
+ // PlzNavigate: |navigation_response_override| is used to override certain
+ // parameters of navigation requests.
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ TakeNavigationResponseOverrideOwnership() {
+ return std::move(navigation_response_override_);
}
- void set_stream_override(
- std::unique_ptr<StreamOverrideParameters> stream_override) {
- stream_override_ = std::move(stream_override);
+ void set_navigation_response_override(
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override) {
+ navigation_response_override_ = std::move(response_override);
}
- // NavigationMojoResponse: |continue_navigation| is used to continue a
- // navigation on the renderer process that has already been started on the
- // browser process.
+ // |continue_navigation| is used to continue a navigation on the renderer
+ // process that has already been started on the browser process.
base::OnceClosure TakeContinueNavigationFunctionOwnerShip() {
return std::move(continue_navigation_function_);
}
@@ -163,14 +160,14 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
bool is_main_frame_;
bool allow_download_;
ui::PageTransition transition_type_;
- bool should_replace_current_entry_;
int service_worker_provider_id_;
bool originated_from_service_worker_;
blink::WebString custom_user_agent_;
blink::WebString requested_with_;
- std::unique_ptr<StreamOverrideParameters> stream_override_;
- // TODO(arthursonzogni): Once NavigationMojoResponse is launched, move most of
- // the |stream_override_| content as parameters of this function.
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ navigation_response_override_;
+ // TODO(arthursonzogni): Move most of the |navigation_response_override_|
+ // content as parameters of this function.
base::OnceClosure continue_navigation_function_;
bool initiated_in_secure_context_;
bool is_for_no_state_prefetch_;
diff --git a/chromium/content/renderer/loader/resource_dispatcher.cc b/chromium/content/renderer/loader/resource_dispatcher.cc
index 8764f8e026f..f3f906a3c5a 100644
--- a/chromium/content/renderer/loader/resource_dispatcher.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher.cc
@@ -14,7 +14,6 @@
#include "base/debug/alias.h"
#include "base/debug/stack_trace.h"
#include "base/files/file_path.h"
-#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/strings/string_util.h"
@@ -24,6 +23,7 @@
#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/navigation_params.h"
#include "content/common/throttling_url_loader.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/resource_load_info.mojom.h"
#include "content/public/common/resource_type.h"
#include "content/public/renderer/fixed_received_data.h"
@@ -119,6 +119,20 @@ void NotifyResourceLoadComplete(
std::move(resource_load_info));
}
+// Returns true if the headers indicate that this resource should always be
+// revalidated or not cached.
+bool AlwaysAccessNetwork(
+ const scoped_refptr<net::HttpResponseHeaders>& headers) {
+ if (!headers)
+ return false;
+
+ // RFC 2616, section 14.9.
+ return headers->HasHeaderValue("cache-control", "no-cache") ||
+ headers->HasHeaderValue("cache-control", "no-store") ||
+ headers->HasHeaderValue("pragma", "no-cache") ||
+ headers->HasHeaderValue("vary", "*");
+}
+
int GetInitialRequestID() {
// Starting with a random number speculatively avoids RDH_INVALID_REQUEST_ID
// which are assumed to have been caused by restarting RequestID at 0 when
@@ -172,13 +186,35 @@ void ResourceDispatcher::OnUploadProgress(int request_id,
void ResourceDispatcher::OnReceivedResponse(
int request_id,
- const network::ResourceResponseHead& response_head) {
+ const network::ResourceResponseHead& initial_response_head) {
TRACE_EVENT0("loader", "ResourceDispatcher::OnReceivedResponse");
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
- request_info->response_start = base::TimeTicks::Now();
+ request_info->local_response_start = base::TimeTicks::Now();
+ request_info->remote_request_start =
+ initial_response_head.load_timing.request_start;
+ // Now that response_start has been set, we can properly set the TimeTicks in
+ // the ResourceResponseInfo.
+ network::ResourceResponseInfo renderer_response_info;
+ ToResourceResponseInfo(*request_info, initial_response_head,
+ &renderer_response_info);
+ request_info->load_timing_info = renderer_response_info.load_timing;
+
+ network::ResourceResponseHead response_head;
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override =
+ std::move(request_info->navigation_response_override);
+ if (response_override) {
+ CHECK(IsBrowserSideNavigationEnabled());
+ response_head = response_override->response;
+ } else {
+ response_head = initial_response_head;
+ }
+ request_info->mime_type = response_head.mime_type;
+ request_info->network_accessed = response_head.network_accessed;
+ request_info->always_access_network =
+ AlwaysAccessNetwork(response_head.headers);
if (delegate_) {
std::unique_ptr<RequestPeer> new_peer = delegate_->OnReceivedResponse(
std::move(request_info->peer), response_head.mime_type,
@@ -186,14 +222,7 @@ void ResourceDispatcher::OnReceivedResponse(
DCHECK(new_peer);
request_info->peer = std::move(new_peer);
}
-
- if (!response_head.socket_address.host().empty()) {
- ignore_result(request_info->parsed_ip.AssignFromIPLiteral(
- response_head.socket_address.host()));
- }
-
- request_info->mime_type = response_head.mime_type;
- request_info->network_accessed = response_head.network_accessed;
+ request_info->host_port_pair = renderer_response_info.socket_address;
if (!IsResourceTypeFrame(request_info->resource_type)) {
NotifySubresourceStarted(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
request_info->render_frame_id,
@@ -201,8 +230,6 @@ void ResourceDispatcher::OnReceivedResponse(
response_head.cert_status);
}
- network::ResourceResponseInfo renderer_response_info;
- ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
request_info->peer->OnReceivedResponse(renderer_response_info);
}
@@ -248,7 +275,8 @@ void ResourceDispatcher::OnReceivedRedirect(
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
- request_info->response_start = base::TimeTicks::Now();
+ request_info->local_response_start = base::TimeTicks::Now();
+ request_info->remote_request_start = response_head.load_timing.request_start;
network::ResourceResponseInfo renderer_response_info;
ToResourceResponseInfo(*request_info, response_head, &renderer_response_info);
@@ -264,9 +292,19 @@ void ResourceDispatcher::OnReceivedRedirect(
request_info->response_method = redirect_info.new_method;
request_info->response_referrer = GURL(redirect_info.new_referrer);
request_info->has_pending_redirect = true;
- if (!request_info->is_deferred) {
+ mojom::RedirectInfoPtr net_redirect_info = mojom::RedirectInfo::New();
+ net_redirect_info->url = redirect_info.new_url;
+ net_redirect_info->network_info = mojom::CommonNetworkInfo::New();
+ net_redirect_info->network_info->network_accessed =
+ response_head.network_accessed;
+ net_redirect_info->network_info->always_access_network =
+ AlwaysAccessNetwork(response_head.headers);
+ net_redirect_info->network_info->ip_port_pair =
+ response_head.socket_address;
+ request_info->redirect_info_chain.push_back(std::move(net_redirect_info));
+
+ if (!request_info->is_deferred)
FollowPendingRedirect(request_info);
- }
} else {
Cancel(request_id, std::move(task_runner));
}
@@ -274,8 +312,11 @@ void ResourceDispatcher::OnReceivedRedirect(
void ResourceDispatcher::FollowPendingRedirect(
PendingRequestInfo* request_info) {
- if (request_info->has_pending_redirect) {
+ if (request_info->has_pending_redirect &&
+ request_info->should_follow_redirect) {
request_info->has_pending_redirect = false;
+ // net::URLRequest clears its request_start on redirect, so should we.
+ request_info->local_request_start = base::TimeTicks::Now();
request_info->url_loader->FollowRedirect();
}
}
@@ -288,7 +329,6 @@ void ResourceDispatcher::OnRequestComplete(
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
- request_info->completion_time = base::TimeTicks::Now();
request_info->buffer.reset();
request_info->buffer_size = 0;
@@ -299,13 +339,21 @@ void ResourceDispatcher::OnRequestComplete(
resource_load_info->method = request_info->response_method;
resource_load_info->resource_type = request_info->resource_type;
resource_load_info->request_id = request_id;
- if (request_info->parsed_ip.IsValid())
- resource_load_info->ip = request_info->parsed_ip;
resource_load_info->mime_type = request_info->mime_type;
- resource_load_info->network_accessed = request_info->network_accessed;
+ resource_load_info->network_info = mojom::CommonNetworkInfo::New();
+ resource_load_info->network_info->network_accessed =
+ request_info->network_accessed;
+ resource_load_info->network_info->always_access_network =
+ request_info->always_access_network;
+ resource_load_info->network_info->ip_port_pair = request_info->host_port_pair;
+ resource_load_info->load_timing_info = request_info->load_timing_info;
resource_load_info->was_cached = status.exists_in_cache;
resource_load_info->net_error = status.error_code;
- resource_load_info->request_start = request_info->request_start;
+ resource_load_info->redirect_info_chain =
+ std::move(request_info->redirect_info_chain);
+ resource_load_info->total_received_bytes = status.encoded_data_length;
+ resource_load_info->raw_body_bytes = status.encoded_body_length;
+
NotifyResourceLoadComplete(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
request_info->render_frame_id,
std::move(resource_load_info));
@@ -320,15 +368,34 @@ void ResourceDispatcher::OnRequestComplete(
request_info->peer = std::move(new_peer);
}
+ network::URLLoaderCompletionStatus renderer_status(status);
+ if (status.completion_time.is_null()) {
+ // No completion timestamp is provided, leave it as is.
+ } else if (request_info->remote_request_start.is_null() ||
+ request_info->load_timing_info.request_start.is_null()) {
+ // We cannot convert the remote time to a local time, let's use the current
+ // timestamp. This happens when
+ // - We get an error before OnReceivedRedirect or OnReceivedResponse is
+ // called, or
+ // - Somehow such a timestamp was missing in the LoadTimingInfo.
+ renderer_status.completion_time = base::TimeTicks::Now();
+ } else {
+ // We have already converted the request start timestamp, let's use that
+ // conversion information.
+ // Note: We cannot create a InterProcessTimeTicksConverter with
+ // (local_request_start, now, remote_request_start, remote_completion_time)
+ // as that may result in inconsistent timestamps.
+ renderer_status.completion_time =
+ std::min(status.completion_time - request_info->remote_request_start +
+ request_info->load_timing_info.request_start,
+ base::TimeTicks::Now());
+ }
// The request ID will be removed from our pending list in the destructor.
// Normally, dispatching this message causes the reference-counted request to
// die immediately.
// TODO(kinuko): Revisit here. This probably needs to call request_info->peer
// but the past attempt to change it seems to have caused crashes.
// (crbug.com/547047)
- network::URLLoaderCompletionStatus renderer_status(status);
- renderer_status.completion_time =
- ToRendererCompletionTime(*request_info, status.completion_time);
peer->OnCompletedRequest(renderer_status);
}
@@ -427,7 +494,9 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
const GURL& request_url,
const std::string& method,
const GURL& referrer,
- bool download_to_file)
+ bool download_to_file,
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ navigation_response_override_params)
: peer(std::move(peer)),
resource_type(resource_type),
render_frame_id(render_frame_id),
@@ -436,7 +505,10 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
response_method(method),
response_referrer(referrer),
download_to_file(download_to_file),
- request_start(base::TimeTicks::Now()) {}
+ local_request_start(base::TimeTicks::Now()),
+ buffer_size(0),
+ navigation_response_override(
+ std::move(navigation_response_override_params)) {}
ResourceDispatcher::PendingRequestInfo::~PendingRequestInfo() {
}
@@ -449,12 +521,13 @@ void ResourceDispatcher::StartSync(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
double timeout,
- blink::mojom::BlobRegistryPtrInfo download_to_blob_registry) {
+ blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
+ std::unique_ptr<RequestPeer> peer) {
CheckSchemeForReferrerPolicy(*request);
std::unique_ptr<network::SharedURLLoaderFactoryInfo> factory_info =
url_loader_factory->Clone();
- base::WaitableEvent completed_event(
+ base::WaitableEvent redirect_or_response_event(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -474,10 +547,32 @@ void ResourceDispatcher::StartSync(
std::move(request), routing_id, task_runner,
traffic_annotation, std::move(factory_info),
std::move(throttles), base::Unretained(response),
- base::Unretained(&completed_event),
+ base::Unretained(&redirect_or_response_event),
base::Unretained(terminate_sync_load_event_), timeout,
std::move(download_to_blob_registry)));
- completed_event.Wait();
+
+ // redirect_or_response_event will signal when each redirect completes, and
+ // when the final response is complete.
+ redirect_or_response_event.Wait();
+
+ while (response->context_for_redirect) {
+ DCHECK(response->redirect_info);
+ bool follow_redirect =
+ peer->OnReceivedRedirect(*response->redirect_info, response->info);
+ redirect_or_response_event.Reset();
+ if (follow_redirect) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SyncLoadContext::FollowRedirect,
+ base::Unretained(response->context_for_redirect)));
+ } else {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SyncLoadContext::CancelRedirect,
+ base::Unretained(response->context_for_redirect)));
+ }
+ redirect_or_response_event.Wait();
+ }
}
int ResourceDispatcher::StartAsync(
@@ -490,27 +585,32 @@ int ResourceDispatcher::StartAsync(
std::unique_ptr<RequestPeer> peer,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ response_override_params,
base::OnceClosure* continue_navigation_function) {
CheckSchemeForReferrerPolicy(*request);
+ bool override_url_loader =
+ !!response_override_params &&
+ !!response_override_params->url_loader_client_endpoints;
+
// Compute a unique request_id for this renderer process.
int request_id = MakeRequestID();
pending_requests_[request_id] = std::make_unique<PendingRequestInfo>(
std::move(peer), static_cast<ResourceType>(request->resource_type),
request->render_frame_id, request->url, request->method,
- request->referrer, request->download_to_file);
+ request->referrer, request->download_to_file,
+ std::move(response_override_params));
- if (url_loader_client_endpoints) {
+ if (override_url_loader) {
pending_requests_[request_id]->url_loader_client =
std::make_unique<URLLoaderClientImpl>(request_id, this,
loading_task_runner);
DCHECK(continue_navigation_function);
- *continue_navigation_function = base::BindOnce(
- &ResourceDispatcher::ContinueForNavigation, weak_factory_.GetWeakPtr(),
- request_id, std::move(url_loader_client_endpoints));
-
+ *continue_navigation_function =
+ base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
+ weak_factory_.GetWeakPtr(), request_id);
return request_id;
}
@@ -550,16 +650,16 @@ void ResourceDispatcher::ToResourceResponseInfo(
network::ResourceResponseInfo* renderer_info) const {
*renderer_info = browser_info;
if (base::TimeTicks::IsConsistentAcrossProcesses() ||
- request_info.request_start.is_null() ||
- request_info.response_start.is_null() ||
+ request_info.local_request_start.is_null() ||
+ request_info.local_response_start.is_null() ||
browser_info.request_start.is_null() ||
browser_info.response_start.is_null() ||
browser_info.load_timing.request_start.is_null()) {
return;
}
InterProcessTimeTicksConverter converter(
- LocalTimeTicks::FromTimeTicks(request_info.request_start),
- LocalTimeTicks::FromTimeTicks(request_info.response_start),
+ LocalTimeTicks::FromTimeTicks(request_info.local_request_start),
+ LocalTimeTicks::FromTimeTicks(request_info.local_response_start),
RemoteTimeTicks::FromTimeTicks(browser_info.request_start),
RemoteTimeTicks::FromTimeTicks(browser_info.response_start));
@@ -582,46 +682,42 @@ void ResourceDispatcher::ToResourceResponseInfo(
RemoteToLocalTimeTicks(converter, &renderer_info->service_worker_ready_time);
}
-base::TimeTicks ResourceDispatcher::ToRendererCompletionTime(
- const PendingRequestInfo& request_info,
- const base::TimeTicks& browser_completion_time) const {
- if (request_info.completion_time.is_null()) {
- return browser_completion_time;
- }
-
- // TODO(simonjam): The optimal lower bound should be the most recent value of
- // TimeTicks::Now() returned to WebKit. Is it worth trying to cache that?
- // Until then, |response_start| is used as it is the most recent value
- // returned for this request.
- int64_t result = std::max(browser_completion_time.ToInternalValue(),
- request_info.response_start.ToInternalValue());
- result = std::min(result, request_info.completion_time.ToInternalValue());
- return base::TimeTicks::FromInternalValue(result);
-}
-
-void ResourceDispatcher::ContinueForNavigation(
- int request_id,
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints) {
- DCHECK(url_loader_client_endpoints);
+void ResourceDispatcher::ContinueForNavigation(int request_id) {
PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
if (!request_info)
return;
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override =
+ std::move(request_info->navigation_response_override);
+ DCHECK(response_override);
+
+ // Mark the request so we do not attempt to follow the redirects, they already
+ // happened.
+ request_info->should_follow_redirect = false;
+
URLLoaderClientImpl* client_ptr = request_info->url_loader_client.get();
+ // PlzNavigate: during navigations, the ResourceResponse has already been
+ // received on the browser side, and has been passed down to the renderer.
+ // Replay the redirects that happened during navigation.
+ DCHECK_EQ(response_override->redirect_responses.size(),
+ response_override->redirect_infos.size());
+ for (size_t i = 0; i < response_override->redirect_responses.size(); ++i) {
+ client_ptr->OnReceiveRedirect(response_override->redirect_infos[i],
+ response_override->redirect_responses[i]);
+ // The request might have been cancelled while processing the redirect.
+ if (!GetPendingRequestInfo(request_id))
+ return;
+ }
- // Short circuiting call to OnReceivedResponse to immediately start
- // the request. ResourceResponseHead can be empty here because we
- // pull the StreamOverride's one in
- // WebURLLoaderImpl::Context::OnReceivedResponse.
- client_ptr->OnReceiveResponse(network::ResourceResponseHead(),
+ client_ptr->OnReceiveResponse(response_override->response,
network::mojom::DownloadedTempFilePtr());
- // TODO(clamy): Move the replaying of redirects from WebURLLoaderImpl here.
// Abort if the request is cancelled.
if (!GetPendingRequestInfo(request_id))
return;
- client_ptr->Bind(std::move(url_loader_client_endpoints));
+ DCHECK(response_override->url_loader_client_endpoints);
+ client_ptr->Bind(std::move(response_override->url_loader_client_endpoints));
}
} // namespace content
diff --git a/chromium/content/renderer/loader/resource_dispatcher.h b/chromium/content/renderer/loader/resource_dispatcher.h
index af1364a8799..609aaef3f2a 100644
--- a/chromium/content/renderer/loader/resource_dispatcher.h
+++ b/chromium/content/renderer/loader/resource_dispatcher.h
@@ -12,6 +12,7 @@
#include <map>
#include <memory>
#include <string>
+#include <vector>
#include "base/containers/circular_deque.h"
#include "base/containers/hash_tables.h"
@@ -22,9 +23,11 @@
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
+#include "content/public/common/resource_load_info.mojom.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/url_loader_throttle.h"
#include "mojo/public/cpp/system/data_pipe.h"
+#include "net/base/host_port_pair.h"
#include "net/base/request_priority.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -52,6 +55,7 @@ class URLLoaderFactory;
}
namespace content {
+struct NavigationResponseOverrideParameters;
class RequestPeer;
class ResourceDispatcherDelegate;
struct SyncLoadResponse;
@@ -96,7 +100,8 @@ class CONTENT_EXPORT ResourceDispatcher {
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
double timeout,
- blink::mojom::BlobRegistryPtrInfo download_to_blob_registry);
+ blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
+ std::unique_ptr<RequestPeer> peer);
// Call this method to initiate the request. If this method succeeds, then
// the peer's methods will be called asynchronously to report various events.
@@ -122,7 +127,8 @@ class CONTENT_EXPORT ResourceDispatcher {
std::unique_ptr<RequestPeer> peer,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ response_override_params,
base::OnceClosure* continue_navigation_function);
network::mojom::DownloadedTempFilePtr TakeDownloadedTempFile(int request_id);
@@ -179,7 +185,9 @@ class CONTENT_EXPORT ResourceDispatcher {
const GURL& request_url,
const std::string& method,
const GURL& referrer,
- bool download_to_file);
+ bool download_to_file,
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ response_override_params);
~PendingRequestInfo();
@@ -196,14 +204,21 @@ class CONTENT_EXPORT ResourceDispatcher {
GURL response_referrer;
bool download_to_file;
bool has_pending_redirect = false;
- base::TimeTicks request_start;
- base::TimeTicks response_start;
- base::TimeTicks completion_time;
+ base::TimeTicks local_request_start;
+ base::TimeTicks local_response_start;
+ base::TimeTicks remote_request_start;
+ net::LoadTimingInfo load_timing_info;
linked_ptr<base::SharedMemory> buffer;
int buffer_size;
- net::IPAddress parsed_ip;
+ net::HostPortPair host_port_pair;
bool network_accessed = false;
std::string mime_type;
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ navigation_response_override;
+ bool should_follow_redirect = true;
+ bool always_access_network = false;
+
+ std::vector<content::mojom::RedirectInfoPtr> redirect_info_chain;
// For mojo loading.
std::unique_ptr<ThrottlingURLLoader> url_loader;
@@ -239,13 +254,7 @@ class CONTENT_EXPORT ResourceDispatcher {
const network::ResourceResponseHead& browser_info,
network::ResourceResponseInfo* renderer_info) const;
- base::TimeTicks ToRendererCompletionTime(
- const PendingRequestInfo& request_info,
- const base::TimeTicks& browser_completion_time) const;
-
- void ContinueForNavigation(
- int request_id,
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
+ void ContinueForNavigation(int request_id);
// All pending requests issued to the host
PendingRequestMap pending_requests_;
diff --git a/chromium/content/renderer/loader/resource_dispatcher_unittest.cc b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
index 32b18cfc520..9d89c8b0198 100644
--- a/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -21,10 +21,10 @@
#include "base/test/scoped_feature_list.h"
#include "content/common/appcache_interfaces.h"
#include "content/public/common/content_features.h"
-#include "content/public/common/weak_wrapper_shared_url_loader_factory.h"
#include "content/public/renderer/fixed_received_data.h"
#include "content/public/renderer/request_peer.h"
#include "content/public/renderer/resource_dispatcher_delegate.h"
+#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/loader/test_request_peer.h"
#include "net/base/net_errors.h"
@@ -34,6 +34,7 @@
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -117,9 +118,9 @@ class ResourceDispatcherTest : public testing::Test,
std::move(request), 0,
blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
TRAFFIC_ANNOTATION_FOR_TESTS, false, false, std::move(peer),
- base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(this),
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(this),
std::vector<std::unique_ptr<URLLoaderThrottle>>(),
- network::mojom::URLLoaderClientEndpointsPtr(),
+ nullptr /* navigation_response_override_params */,
nullptr /* continue_navigation_function */);
peer_context->request_id = request_id;
return request_id;
@@ -377,4 +378,85 @@ TEST_F(TimeConversionTest, NotInitialized) {
response_info().load_timing.connect_timing.dns_start);
}
+class CompletionTimeConversionTest : public ResourceDispatcherTest {
+ public:
+ void PerformTest(base::TimeTicks remote_request_start,
+ base::TimeTicks completion_time,
+ base::TimeDelta delay) {
+ std::unique_ptr<network::ResourceRequest> request(CreateResourceRequest());
+ StartAsync(std::move(request), nullptr, &peer_context_);
+
+ ASSERT_EQ(1u, loader_and_clients_.size());
+ auto client = std::move(loader_and_clients_[0].second);
+ network::ResourceResponseHead response_head;
+ response_head.request_start = remote_request_start;
+ response_head.load_timing.request_start = remote_request_start;
+ response_head.load_timing.receive_headers_end = remote_request_start;
+ // We need to put somthing non-null time, otherwise no values will be
+ // copied.
+ response_head.load_timing.request_start_time =
+ base::Time() + base::TimeDelta::FromSeconds(99);
+ client->OnReceiveResponse(response_head, {});
+
+ network::URLLoaderCompletionStatus status;
+ status.completion_time = completion_time;
+
+ client->OnComplete(status);
+
+ const base::TimeTicks until = base::TimeTicks::Now() + delay;
+ while (base::TimeTicks::Now() < until)
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
+ base::RunLoop().RunUntilIdle();
+ loader_and_clients_.clear();
+ }
+
+ base::TimeTicks request_start() const {
+ EXPECT_TRUE(peer_context_.received_response);
+ return peer_context_.last_load_timing.request_start;
+ }
+ base::TimeTicks completion_time() const {
+ EXPECT_TRUE(peer_context_.complete);
+ return peer_context_.completion_status.completion_time;
+ }
+
+ private:
+ TestRequestPeer::Context peer_context_;
+};
+
+TEST_F(CompletionTimeConversionTest, NullCompletionTimestamp) {
+ const auto remote_request_start =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(4);
+
+ PerformTest(remote_request_start, base::TimeTicks(), base::TimeDelta());
+
+ EXPECT_EQ(base::TimeTicks(), completion_time());
+}
+
+TEST_F(CompletionTimeConversionTest, RemoteRequestStartIsUnavailable) {
+ base::TimeTicks begin = base::TimeTicks::Now();
+
+ const auto remote_completion_time =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(8);
+
+ PerformTest(base::TimeTicks(), remote_completion_time, base::TimeDelta());
+
+ base::TimeTicks end = base::TimeTicks::Now();
+ EXPECT_LE(begin, completion_time());
+ EXPECT_LE(completion_time(), end);
+}
+
+TEST_F(CompletionTimeConversionTest, Convert) {
+ const auto remote_request_start =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(4);
+
+ const auto remote_completion_time =
+ remote_request_start + base::TimeDelta::FromMilliseconds(3);
+
+ PerformTest(remote_request_start, remote_completion_time,
+ base::TimeDelta::FromMilliseconds(15));
+
+ EXPECT_EQ(completion_time(),
+ request_start() + base::TimeDelta::FromMilliseconds(3));
+}
+
} // namespace content
diff --git a/chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc b/chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc
index 2551ead92fa..f302985c610 100644
--- a/chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc
+++ b/chromium/content/renderer/loader/shared_memory_data_consumer_handle.cc
@@ -11,7 +11,6 @@
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/content/renderer/loader/sync_load_context.cc b/chromium/content/renderer/loader/sync_load_context.cc
index fc94a225897..17da79d30b5 100644
--- a/chromium/content/renderer/loader/sync_load_context.cc
+++ b/chromium/content/renderer/loader/sync_load_context.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/synchronization/waitable_event.h"
#include "content/public/common/url_loader_throttle.h"
+#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/sync_load_response.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h"
@@ -16,6 +17,59 @@
namespace content {
+// An inner helper class to manage the SyncLoadContext's events and timeouts,
+// so that we can stop or resumse all of them at once.
+class SyncLoadContext::SignalHelper final {
+ public:
+ SignalHelper(SyncLoadContext* context,
+ base::WaitableEvent* redirect_or_response_event,
+ base::WaitableEvent* abort_event,
+ double timeout)
+ : context_(context),
+ redirect_or_response_event_(redirect_or_response_event),
+ abort_event_(abort_event) {
+ Start(base::TimeDelta::FromSecondsD(timeout));
+ }
+
+ void SignalRedirectOrResponseComplete() {
+ abort_watcher_.StopWatching();
+ timeout_timer_.AbandonAndStop();
+ redirect_or_response_event_->Signal();
+ }
+
+ bool RestartAfterRedirect() {
+ if (abort_event_ && abort_event_->IsSignaled())
+ return false;
+ base::TimeDelta timeout_remainder =
+ timeout_timer_.desired_run_time() - base::TimeTicks::Now();
+ if (timeout_remainder <= base::TimeDelta())
+ return false;
+ Start(timeout_remainder);
+ return true;
+ }
+
+ private:
+ void Start(const base::TimeDelta& timeout) {
+ DCHECK(!redirect_or_response_event_->IsSignaled());
+ if (abort_event_) {
+ abort_watcher_.StartWatching(
+ abort_event_,
+ base::BindOnce(&SyncLoadContext::OnAbort, base::Unretained(context_)),
+ context_->task_runner_);
+ }
+ if (timeout > base::TimeDelta()) {
+ timeout_timer_.Start(FROM_HERE, timeout, context_,
+ &SyncLoadContext::OnTimeout);
+ }
+ }
+
+ SyncLoadContext* context_;
+ base::WaitableEvent* redirect_or_response_event_;
+ base::WaitableEvent* abort_event_;
+ base::WaitableEventWatcher abort_watcher_;
+ base::OneShotTimer timeout_timer_;
+};
+
// static
void SyncLoadContext::StartAsyncWithWaitableEvent(
std::unique_ptr<network::ResourceRequest> request,
@@ -26,21 +80,21 @@ void SyncLoadContext::StartAsyncWithWaitableEvent(
url_loader_factory_info,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
SyncLoadResponse* response,
- base::WaitableEvent* completed_event,
+ base::WaitableEvent* redirect_or_response_event,
base::WaitableEvent* abort_event,
double timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry) {
bool download_to_blob = download_to_blob_registry.is_valid();
auto* context = new SyncLoadContext(
request.get(), std::move(url_loader_factory_info), response,
- completed_event, abort_event, timeout,
+ redirect_or_response_event, abort_event, timeout,
std::move(download_to_blob_registry), loading_task_runner);
context->request_id_ = context->resource_dispatcher_->StartAsync(
std::move(request), routing_id, std::move(loading_task_runner),
traffic_annotation, true /* is_sync */,
download_to_blob /* pass_response_pipe_to_peer */,
base::WrapUnique(context), context->url_loader_factory_,
- std::move(throttles), network::mojom::URLLoaderClientEndpointsPtr(),
+ std::move(throttles), nullptr /* navigation_response_override_params */,
nullptr /* continue_for_navigation */);
}
@@ -48,27 +102,21 @@ SyncLoadContext::SyncLoadContext(
network::ResourceRequest* request,
std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory,
SyncLoadResponse* response,
- base::WaitableEvent* completed_event,
+ base::WaitableEvent* redirect_or_response_event,
base::WaitableEvent* abort_event,
double timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: response_(response),
- completed_event_(completed_event),
download_to_blob_registry_(std::move(download_to_blob_registry)),
- task_runner_(std::move(task_runner)) {
+ task_runner_(std::move(task_runner)),
+ signals_(std::make_unique<SignalHelper>(this,
+ redirect_or_response_event,
+ abort_event,
+ timeout)),
+ fetch_request_mode_(request->fetch_request_mode) {
url_loader_factory_ =
network::SharedURLLoaderFactory::Create(std::move(url_loader_factory));
- if (abort_event) {
- abort_watcher_.StartWatching(
- abort_event,
- base::BindOnce(&SyncLoadContext::OnAbort, base::Unretained(this)),
- task_runner_);
- }
- if (timeout) {
- timeout_timer_.Start(FROM_HERE, base::TimeDelta::FromSecondsD(timeout),
- this, &SyncLoadContext::OnTimeout);
- }
// Constructs a new ResourceDispatcher specifically for this request.
resource_dispatcher_ = std::make_unique<ResourceDispatcher>();
@@ -86,7 +134,13 @@ bool SyncLoadContext::OnReceivedRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseInfo& info) {
DCHECK(!Completed());
- if (redirect_info.new_url.GetOrigin() != response_->url.GetOrigin()) {
+ // Synchronous loads in blink aren't associated with a ResourceClient, and
+ // CORS checks are performed by ResourceClient subclasses, so there's
+ // currently no way to perform CORS checks for redirects.
+ // Err on the side of extreme caution and block any cross origin redirect
+ // that might have CORS implications.
+ if (fetch_request_mode_ != network::mojom::FetchRequestMode::kNoCORS &&
+ redirect_info.new_url.GetOrigin() != response_->url.GetOrigin()) {
LOG(ERROR) << "Cross origin redirect denied";
response_->error_code = net::ERR_ABORTED;
@@ -98,9 +152,33 @@ bool SyncLoadContext::OnReceivedRedirect(
}
response_->url = redirect_info.new_url;
+ response_->info = info;
+ response_->redirect_info = redirect_info;
+ response_->context_for_redirect = this;
+ resource_dispatcher_->SetDefersLoading(request_id_, true);
+ signals_->SignalRedirectOrResponseComplete();
return true;
}
+void SyncLoadContext::FollowRedirect() {
+ if (!signals_->RestartAfterRedirect()) {
+ CancelRedirect();
+ return;
+ }
+
+ response_->redirect_info = net::RedirectInfo();
+ response_->context_for_redirect = nullptr;
+
+ resource_dispatcher_->SetDefersLoading(request_id_, false);
+}
+
+void SyncLoadContext::CancelRedirect() {
+ response_->redirect_info = net::RedirectInfo();
+ response_->context_for_redirect = nullptr;
+ response_->error_code = net::ERR_ABORTED;
+ CompleteRequest(true);
+}
+
void SyncLoadContext::OnReceivedResponse(
const network::ResourceResponseInfo& info) {
DCHECK(!Completed());
@@ -181,12 +259,8 @@ void SyncLoadContext::OnTimeout() {
}
void SyncLoadContext::CompleteRequest(bool remove_pending_request) {
- abort_watcher_.StopWatching();
- timeout_timer_.AbandonAndStop();
-
- completed_event_->Signal();
-
- completed_event_ = nullptr;
+ signals_->SignalRedirectOrResponseComplete();
+ signals_ = nullptr;
response_ = nullptr;
if (remove_pending_request) {
@@ -196,7 +270,7 @@ void SyncLoadContext::CompleteRequest(bool remove_pending_request) {
}
bool SyncLoadContext::Completed() const {
- DCHECK_EQ(!completed_event_, !response_);
+ DCHECK_EQ(!signals_, !response_);
return !response_;
}
diff --git a/chromium/content/renderer/loader/sync_load_context.h b/chromium/content/renderer/loader/sync_load_context.h
index b0b474405a3..23a7e7e8094 100644
--- a/chromium/content/renderer/loader/sync_load_context.h
+++ b/chromium/content/renderer/loader/sync_load_context.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/optional.h"
+#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event_watcher.h"
#include "base/timer/timer.h"
#include "content/public/renderer/request_peer.h"
@@ -54,6 +55,9 @@ class SyncLoadContext : public RequestPeer {
~SyncLoadContext() override;
+ void FollowRedirect();
+ void CancelRedirect();
+
private:
SyncLoadContext(
network::ResourceRequest* request,
@@ -90,10 +94,6 @@ class SyncLoadContext : public RequestPeer {
// Set to null after CompleteRequest() is called.
SyncLoadResponse* response_;
- // This event is signaled when the request is complete.
- // Set to null after CompleteRequest() is called.
- base::WaitableEvent* completed_event_;
-
// State necessary to run a request on an independent thread.
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
@@ -110,8 +110,10 @@ class SyncLoadContext : public RequestPeer {
base::Optional<int64_t> downloaded_file_length_;
- base::WaitableEventWatcher abort_watcher_;
- base::OneShotTimer timeout_timer_;
+ class SignalHelper;
+ std::unique_ptr<SignalHelper> signals_;
+
+ const network::mojom::FetchRequestMode fetch_request_mode_;
DISALLOW_COPY_AND_ASSIGN(SyncLoadContext);
};
diff --git a/chromium/content/renderer/loader/sync_load_response.h b/chromium/content/renderer/loader/sync_load_response.h
index bd46a9b14a9..ea252ca5f31 100644
--- a/chromium/content/renderer/loader/sync_load_response.h
+++ b/chromium/content/renderer/loader/sync_load_response.h
@@ -17,6 +17,8 @@
namespace content {
+class SyncLoadContext;
+
// See the SyncLoad method. (The name of this struct is not
// suffixed with "Info" because it also contains the response data.)
struct CONTENT_EXPORT SyncLoadResponse {
@@ -26,6 +28,9 @@ struct CONTENT_EXPORT SyncLoadResponse {
SyncLoadResponse& operator=(SyncLoadResponse&& other);
+ base::Optional<net::RedirectInfo> redirect_info;
+ SyncLoadContext* context_for_redirect = nullptr;
+
network::ResourceResponseInfo info;
// The response error code.
diff --git a/chromium/content/renderer/loader/test_request_peer.cc b/chromium/content/renderer/loader/test_request_peer.cc
index 42b46e16e41..1d92c02c630 100644
--- a/chromium/content/renderer/loader/test_request_peer.cc
+++ b/chromium/content/renderer/loader/test_request_peer.cc
@@ -27,6 +27,7 @@ bool TestRequestPeer::OnReceivedRedirect(
EXPECT_FALSE(context_->cancelled);
EXPECT_FALSE(context_->complete);
++context_->seen_redirects;
+ context_->last_load_timing = info.load_timing;
if (context_->defer_on_redirect)
dispatcher_->SetDefersLoading(context_->request_id, true);
return context_->follow_redirects;
@@ -38,6 +39,7 @@ void TestRequestPeer::OnReceivedResponse(
EXPECT_FALSE(context_->received_response);
EXPECT_FALSE(context_->complete);
context_->received_response = true;
+ context_->last_load_timing = info.load_timing;
if (context_->cancel_on_receive_response) {
dispatcher_->Cancel(
context_->request_id,
@@ -101,6 +103,7 @@ void TestRequestPeer::OnCompletedRequest(
EXPECT_TRUE(context_->received_response);
EXPECT_FALSE(context_->complete);
context_->complete = true;
+ context_->completion_status = status;
}
TestRequestPeer::Context::Context() = default;
diff --git a/chromium/content/renderer/loader/test_request_peer.h b/chromium/content/renderer/loader/test_request_peer.h
index 06e3a24e7c0..3c40627b410 100644
--- a/chromium/content/renderer/loader/test_request_peer.h
+++ b/chromium/content/renderer/loader/test_request_peer.h
@@ -11,6 +11,8 @@
#include <vector>
#include "base/time/time.h"
#include "content/public/renderer/request_peer.h"
+#include "net/base/load_timing_info.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
namespace net {
struct RedirectInfo;
@@ -77,6 +79,9 @@ class TestRequestPeer : public RequestPeer {
bool complete = false;
bool cancelled = false;
int request_id = -1;
+
+ net::LoadTimingInfo last_load_timing;
+ network::URLLoaderCompletionStatus completion_status;
};
private:
diff --git a/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h b/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h
index aaa4289f50c..d76f70f6355 100644
--- a/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h
+++ b/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_RENDERER_LOADER_TRACKED_CHILD_URL_LOADER_FACTORY_BUNDLE_H_
#define CONTENT_RENDERER_LOADER_TRACKED_CHILD_URL_LOADER_FACTORY_BUNDLE_H_
+#include "base/sequenced_task_runner.h"
#include "content/common/content_export.h"
#include "content/renderer/loader/child_url_loader_factory_bundle.h"
diff --git a/chromium/content/renderer/loader/url_loader_client_impl.h b/chromium/content/renderer/loader/url_loader_client_impl.h
index 96712b00667..66c1a455214 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl.h
+++ b/chromium/content/renderer/loader/url_loader_client_impl.h
@@ -60,10 +60,9 @@ class CONTENT_EXPORT URLLoaderClientImpl final
// Binds this instance to the given URLLoaderClient endpoints so that it can
// start getting the mojo calls from the given loader. This is used only for
- // the main resource loading when NavigationMojoResponse and/or NetworkService
- // is enabled. Otherwise (in regular subresource loading cases) |this| is not
- // bound to a client request, but used via ThrottlingURLLoader to get client
- // upcalls from the loader.
+ // the main resource loading. Otherwise (in regular subresource loading cases)
+ // |this| is not bound to a client request, but used via ThrottlingURLLoader
+ // to get client upcalls from the loader.
void Bind(
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
@@ -112,7 +111,6 @@ class CONTENT_EXPORT URLLoaderClientImpl final
ResourceDispatcher* const resource_dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- // Used in NavigationMojoResponse and NetworkService.
network::mojom::URLLoaderPtr url_loader_;
mojo::Binding<network::mojom::URLLoaderClient> url_loader_client_binding_;
diff --git a/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
index 9c00707535e..4278bd904a9 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -7,13 +7,14 @@
#include <vector>
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "content/public/common/weak_wrapper_shared_url_loader_factory.h"
+#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/resource_dispatcher.h"
#include "content/renderer/loader/test_request_peer.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -30,9 +31,9 @@ class URLLoaderClientImplTest : public ::testing::Test,
TRAFFIC_ANNOTATION_FOR_TESTS, false, false,
std::make_unique<TestRequestPeer>(dispatcher_.get(),
&request_peer_context_),
- base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(this),
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(this),
std::vector<std::unique_ptr<URLLoaderThrottle>>(),
- network::mojom::URLLoaderClientEndpointsPtr(),
+ nullptr /* navigation_response_override_params */,
nullptr /* continue_navigation_function */);
request_peer_context_.request_id = request_id_;
@@ -62,7 +63,7 @@ class URLLoaderClientImplTest : public ::testing::Test,
static MojoCreateDataPipeOptions DataPipeOptions() {
MojoCreateDataPipeOptions options;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
- options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
options.element_num_bytes = 1;
options.capacity_num_bytes = 4096;
return options;
diff --git a/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
index 49cb00b247c..3038533caa2 100644
--- a/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
+++ b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
@@ -10,14 +10,15 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "content/public/common/weak_wrapper_shared_url_loader_factory.h"
#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/loader/resource_dispatcher.h"
#include "net/base/request_priority.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -143,7 +144,7 @@ class URLResponseBodyConsumerTest : public ::testing::Test {
MojoCreateDataPipeOptions CreateDataPipeOptions() {
MojoCreateDataPipeOptions options;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
- options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
options.element_num_bytes = 1;
options.capacity_num_bytes = 1024;
return options;
@@ -158,9 +159,10 @@ class URLResponseBodyConsumerTest : public ::testing::Test {
TRAFFIC_ANNOTATION_FOR_TESTS, false,
false /* pass_response_pipe_to_peer */,
std::make_unique<TestRequestPeer>(context, message_loop_.task_runner()),
- base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(&factory_),
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &factory_),
std::vector<std::unique_ptr<URLLoaderThrottle>>(),
- network::mojom::URLLoaderClientEndpointsPtr(),
+ nullptr /* navigation_response_override_params */,
nullptr /* continue_navigation_function */);
}
diff --git a/chromium/content/renderer/loader/web_data_consumer_handle_impl.cc b/chromium/content/renderer/loader/web_data_consumer_handle_impl.cc
index b97d43b62cc..c05041f207c 100644
--- a/chromium/content/renderer/loader/web_data_consumer_handle_impl.cc
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl.cc
@@ -81,7 +81,7 @@ Result WebDataConsumerHandleImpl::ReaderImpl::Read(void* data,
context_->handle()->ReadData(data, &size_to_pass, flags_to_pass);
if (rv == MOJO_RESULT_OK)
*read_size = size_to_pass;
- if (rv == MOJO_RESULT_OK || rv == MOJO_RESULT_SHOULD_WAIT)
+ if (rv == MOJO_RESULT_SHOULD_WAIT)
handle_watcher_.ArmOrNotify();
return HandleReadResult(rv);
@@ -104,13 +104,13 @@ Result WebDataConsumerHandleImpl::ReaderImpl::BeginRead(const void** buffer,
context_->handle()->BeginReadData(buffer, &size_to_pass, flags_to_pass);
if (rv == MOJO_RESULT_OK)
*available = size_to_pass;
+ if (rv == MOJO_RESULT_SHOULD_WAIT)
+ handle_watcher_.ArmOrNotify();
return HandleReadResult(rv);
}
Result WebDataConsumerHandleImpl::ReaderImpl::EndRead(size_t read_size) {
MojoResult rv = context_->handle()->EndReadData(read_size);
- if (rv == MOJO_RESULT_OK)
- handle_watcher_.ArmOrNotify();
return rv == MOJO_RESULT_OK ? kOk : kUnexpectedError;
}
diff --git a/chromium/content/renderer/loader/web_data_consumer_handle_impl.h b/chromium/content/renderer/loader/web_data_consumer_handle_impl.h
index 83427b1149e..f79cb797b8e 100644
--- a/chromium/content/renderer/loader/web_data_consumer_handle_impl.h
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl.h
@@ -9,6 +9,7 @@
#include <memory>
+#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
diff --git a/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc b/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
index b01e4800a3d..8e4f0a216a5 100644
--- a/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
@@ -196,7 +196,7 @@ class WebDataConsumerHandleImplTest : public ::testing::Test {
void SetUp() override {
MojoCreateDataPipeOptions options;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
- options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
options.element_num_bytes = 1;
options.capacity_num_bytes = kDataPipeCapacity;
@@ -326,7 +326,7 @@ class CountDidGetReadableClient : public blink::WebDataConsumerHandle::Client {
TEST_F(WebDataConsumerHandleImplTest, DidGetReadable) {
static constexpr size_t kBlockSize = kDataPipeCapacity / 3;
- static constexpr size_t kTotalSize = kBlockSize * 3;
+ static constexpr size_t kTotalSize = kBlockSize * 2;
std::unique_ptr<CountDidGetReadableClient> client =
std::make_unique<CountDidGetReadableClient>();
@@ -337,7 +337,7 @@ TEST_F(WebDataConsumerHandleImplTest, DidGetReadable) {
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0, client->num_did_get_readable_called());
- // Push three blocks.
+ // Push two blocks.
{
std::string expected;
int index = 0;
@@ -365,10 +365,10 @@ TEST_F(WebDataConsumerHandleImplTest, DidGetReadable) {
EXPECT_EQ(sizeof(buffer), size);
}
base::RunLoop().RunUntilIdle();
- // |client| is notified the pipe is still ready.
- EXPECT_EQ(2, client->num_did_get_readable_called());
+ // |client| is NOT notified since the data is still available.
+ EXPECT_EQ(1, client->num_did_get_readable_called());
- // Read one more block.
+ // Read the other block.
{
const void* buffer = nullptr;
size_t size = sizeof(buffer);
@@ -378,28 +378,38 @@ TEST_F(WebDataConsumerHandleImplTest, DidGetReadable) {
EXPECT_TRUE(buffer);
EXPECT_EQ(kTotalSize - kBlockSize, size);
base::RunLoop().RunUntilIdle();
- // |client| is NOT notified until EndRead is called.
- EXPECT_EQ(2, client->num_did_get_readable_called());
rv = reader->EndRead(kBlockSize);
EXPECT_EQ(Result::kOk, rv);
}
base::RunLoop().RunUntilIdle();
- // |client| is notified the pipe is still ready.
- EXPECT_EQ(3, client->num_did_get_readable_called());
+ // |client| is NOT notified the pipe is still waiting for more data.
+ EXPECT_EQ(1, client->num_did_get_readable_called());
- // Read the final block.
+ // Read one more.
{
char buffer[kBlockSize];
size_t size = 0;
Result rv = reader->Read(&buffer, sizeof(buffer),
WebDataConsumerHandle::kFlagNone, &size);
- EXPECT_EQ(Result::kOk, rv);
- EXPECT_EQ(sizeof(buffer), size);
+ EXPECT_EQ(Result::kShouldWait, rv);
+ }
+ base::RunLoop().RunUntilIdle();
+ // |client| is NOT notified because the pipe is still waiting for more data.
+ EXPECT_EQ(1, client->num_did_get_readable_called());
+
+ // Push one more block.
+ {
+ std::string expected(kBlockSize, 'x');
+ uint32_t size = expected.size();
+ MojoResult rv =
+ producer_->WriteData(expected.data(), &size, MOJO_WRITE_DATA_FLAG_NONE);
+ EXPECT_EQ(MOJO_RESULT_OK, rv);
+ EXPECT_EQ(expected.size(), size);
}
base::RunLoop().RunUntilIdle();
- // |client| is NOT notified because the pipe doesn't have any data.
- EXPECT_EQ(3, client->num_did_get_readable_called());
+ // |client| is notified the pipe gets ready.
+ EXPECT_EQ(2, client->num_did_get_readable_called());
}
} // namespace
diff --git a/chromium/content/renderer/loader/web_url_loader_impl.cc b/chromium/content/renderer/loader/web_url_loader_impl.cc
index 0c2ed0fbdce..c1ece37554f 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl.cc
@@ -142,32 +142,21 @@ void PopulateURLLoadTiming(const net::LoadTimingInfo& load_timing,
WebURLLoadTiming* url_timing) {
DCHECK(!load_timing.request_start.is_null());
- const TimeTicks kNullTicks;
url_timing->Initialize();
- url_timing->SetRequestTime(
- (load_timing.request_start - kNullTicks).InSecondsF());
- url_timing->SetProxyStart(
- (load_timing.proxy_resolve_start - kNullTicks).InSecondsF());
- url_timing->SetProxyEnd(
- (load_timing.proxy_resolve_end - kNullTicks).InSecondsF());
- url_timing->SetDNSStart(
- (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF());
- url_timing->SetDNSEnd(
- (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF());
- url_timing->SetConnectStart(
- (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF());
- url_timing->SetConnectEnd(
- (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF());
- url_timing->SetSSLStart(
- (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF());
- url_timing->SetSSLEnd(
- (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF());
- url_timing->SetSendStart((load_timing.send_start - kNullTicks).InSecondsF());
- url_timing->SetSendEnd((load_timing.send_end - kNullTicks).InSecondsF());
- url_timing->SetReceiveHeadersEnd(
- (load_timing.receive_headers_end - kNullTicks).InSecondsF());
- url_timing->SetPushStart((load_timing.push_start - kNullTicks).InSecondsF());
- url_timing->SetPushEnd((load_timing.push_end - kNullTicks).InSecondsF());
+ url_timing->SetRequestTime(load_timing.request_start);
+ url_timing->SetProxyStart(load_timing.proxy_resolve_start);
+ url_timing->SetProxyEnd(load_timing.proxy_resolve_end);
+ url_timing->SetDNSStart(load_timing.connect_timing.dns_start);
+ url_timing->SetDNSEnd(load_timing.connect_timing.dns_end);
+ url_timing->SetConnectStart(load_timing.connect_timing.connect_start);
+ url_timing->SetConnectEnd(load_timing.connect_timing.connect_end);
+ url_timing->SetSSLStart(load_timing.connect_timing.ssl_start);
+ url_timing->SetSSLEnd(load_timing.connect_timing.ssl_end);
+ url_timing->SetSendStart(load_timing.send_start);
+ url_timing->SetSendEnd(load_timing.send_end);
+ url_timing->SetReceiveHeadersEnd(load_timing.receive_headers_end);
+ url_timing->SetPushStart(load_timing.push_start);
+ url_timing->SetPushEnd(load_timing.push_end);
}
net::RequestPriority ConvertWebKitPriorityToNetPriority(
@@ -363,12 +352,6 @@ void SetSecurityStyleAndDetails(const GURL& url,
} // namespace
-StreamOverrideParameters::StreamOverrideParameters() {}
-StreamOverrideParameters::~StreamOverrideParameters() {
- if (on_delete)
- std::move(on_delete).Run(stream_url);
-}
-
WebURLLoaderFactoryImpl::WebURLLoaderFactoryImpl(
base::WeakPtr<ResourceDispatcher> resource_dispatcher,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
@@ -469,7 +452,6 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context> {
ResourceDispatcher* resource_dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::unique_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_;
- std::unique_ptr<StreamOverrideParameters> stream_override_;
std::unique_ptr<SharedMemoryDataConsumerHandle::Writer> body_stream_writer_;
std::unique_ptr<KeepAliveHandleWithChildProcessReference> keep_alive_handle_;
enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA};
@@ -630,10 +612,11 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
return;
}
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override;
if (request.GetExtraData()) {
RequestExtraData* extra_data =
static_cast<RequestExtraData*>(request.GetExtraData());
- stream_override_ = extra_data->TakeStreamOverrideOwnership();
+ response_override = extra_data->TakeNavigationResponseOverrideOwnership();
}
@@ -641,7 +624,7 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
// the WebURLLoader are the ones created by CommitNavigation. Several browser
// tests load HTML directly through a data url which will be handled by the
// block above.
- DCHECK(!IsBrowserSideNavigationEnabled() || stream_override_ ||
+ DCHECK(response_override ||
request.GetFrameType() ==
network::mojom::RequestContextFrameType::kNone);
@@ -686,6 +669,11 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
network::kDefaultAcceptHeader);
}
+ if (resource_request->resource_type == RESOURCE_TYPE_PREFETCH ||
+ resource_request->resource_type == RESOURCE_TYPE_FAVICON) {
+ resource_request->do_not_prompt_for_login = true;
+ }
+
resource_request->load_flags = GetLoadFlagsForWebURLRequest(request);
// |plugin_child_id| only needs to be non-zero if the request originates
@@ -725,22 +713,13 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->previews_state =
static_cast<int>(request.GetPreviewsState());
- // PlzNavigate: The network request has already been made by the browser.
- // The renderer should request a stream which contains the body of the
- // response. If the Network Service or NavigationMojoResponse is enabled, the
- // URLLoaderClientEndpoints is used instead to get the body.
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
- if (stream_override_) {
- CHECK(IsBrowserSideNavigationEnabled());
+ // The network request has already been made by the browser. The renderer
+ // should bind the URLLoaderClientEndpoints stored in |response_override| to
+ // an implementation of a URLLoaderClient to get the response body.
+ if (response_override) {
DCHECK(!sync_load_response);
DCHECK_NE(network::mojom::RequestContextFrameType::kNone,
request.GetFrameType());
- if (stream_override_->url_loader_client_endpoints) {
- url_loader_client_endpoints =
- std::move(stream_override_->url_loader_client_endpoints);
- } else {
- resource_request->resource_body_stream_url = stream_override_->stream_url;
- }
}
RequestExtraData empty_extra_data;
@@ -751,6 +730,16 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
extra_data = &empty_extra_data;
extra_data->CopyToResourceRequest(resource_request.get());
+ std::unique_ptr<RequestPeer> peer;
+ if (extra_data->download_to_network_cache_only()) {
+ peer = std::make_unique<SinkPeer>(this);
+ } else {
+ const bool discard_body =
+ (resource_request->resource_type == RESOURCE_TYPE_PREFETCH);
+ peer =
+ std::make_unique<WebURLLoaderImpl::RequestPeerImpl>(this, discard_body);
+ }
+
if (sync_load_response) {
DCHECK(defers_loading_ == NOT_DEFERRING);
@@ -763,20 +752,11 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
std::move(resource_request), request.RequestorID(),
GetTrafficAnnotationTag(request), sync_load_response,
url_loader_factory_, extra_data->TakeURLLoaderThrottles(),
- request.TimeoutInterval(), std::move(download_to_blob_registry));
+ request.TimeoutInterval(), std::move(download_to_blob_registry),
+ std::move(peer));
return;
}
- std::unique_ptr<RequestPeer> peer;
- if (extra_data->download_to_network_cache_only()) {
- peer = std::make_unique<SinkPeer>(this);
- } else {
- const bool discard_body =
- (resource_request->resource_type == RESOURCE_TYPE_PREFETCH);
- peer =
- std::make_unique<WebURLLoaderImpl::RequestPeerImpl>(this, discard_body);
- }
-
TRACE_EVENT_WITH_FLOW0("loading", "WebURLLoaderImpl::Context::Start", this,
TRACE_EVENT_FLAG_FLOW_OUT);
base::OnceClosure continue_navigation_function;
@@ -784,8 +764,8 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
std::move(resource_request), request.RequestorID(), task_runner_,
GetTrafficAnnotationTag(request), false /* is_sync */,
request.PassResponsePipeToClient(), std::move(peer), url_loader_factory_,
- extra_data->TakeURLLoaderThrottles(),
- std::move(url_loader_client_endpoints), &continue_navigation_function);
+ extra_data->TakeURLLoaderThrottles(), std::move(response_override),
+ &continue_navigation_function);
extra_data->set_continue_navigation_function(
std::move(continue_navigation_function));
@@ -823,7 +803,7 @@ bool WebURLLoaderImpl::Context::OnReceivedRedirect(
}
void WebURLLoaderImpl::Context::OnReceivedResponse(
- const network::ResourceResponseInfo& initial_info) {
+ const network::ResourceResponseInfo& info) {
if (!client_)
return;
@@ -831,25 +811,6 @@ void WebURLLoaderImpl::Context::OnReceivedResponse(
"loading", "WebURLLoaderImpl::Context::OnReceivedResponse",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
- network::ResourceResponseInfo info = initial_info;
-
- // PlzNavigate: during navigations, the ResourceResponse has already been
- // received on the browser side, and has been passed down to the renderer.
- if (stream_override_) {
- CHECK(IsBrowserSideNavigationEnabled());
- info = stream_override_->response;
-
- // Replay the redirects that happened during navigation.
- DCHECK_EQ(stream_override_->redirect_responses.size(),
- stream_override_->redirect_infos.size());
- for (size_t i = 0; i < stream_override_->redirect_responses.size(); ++i) {
- bool result = OnReceivedRedirect(stream_override_->redirect_infos[i],
- stream_override_->redirect_responses[i]);
- if (!result)
- return;
- }
- }
-
WebURLResponse response;
PopulateURLResponse(url_, info, &response, report_raw_headers_);
@@ -1001,10 +962,9 @@ void WebURLLoaderImpl::Context::OnCompletedRequest(
WebURLError::IsWebSecurityViolation::kFalse, url_),
total_transfer_size, encoded_body_size, status.decoded_body_length);
} else {
- client_->DidFinishLoading(
- (status.completion_time - TimeTicks()).InSecondsF(),
- total_transfer_size, encoded_body_size, status.decoded_body_length,
- status.blocked_cross_site_document);
+ client_->DidFinishLoading(status.completion_time, total_transfer_size,
+ encoded_body_size, status.decoded_body_length,
+ status.blocked_cross_site_document);
}
}
}
@@ -1266,11 +1226,8 @@ void WebURLLoaderImpl::PopulateURLResponse(
if (!info.load_timing.receive_headers_end.is_null()) {
WebURLLoadTiming timing;
PopulateURLLoadTiming(info.load_timing, &timing);
- const TimeTicks kNullTicks;
- timing.SetWorkerStart(
- (info.service_worker_start_time - kNullTicks).InSecondsF());
- timing.SetWorkerReady(
- (info.service_worker_ready_time - kNullTicks).InSecondsF());
+ timing.SetWorkerStart(info.service_worker_start_time);
+ timing.SetWorkerReady(info.service_worker_ready_time);
response->SetLoadTiming(timing);
}
@@ -1334,6 +1291,7 @@ void WebURLLoaderImpl::PopulateURLResponse(
void WebURLLoaderImpl::LoadSynchronously(
const WebURLRequest& request,
+ WebURLLoaderClient* client,
WebURLResponse& response,
base::Optional<WebURLError>& error,
WebData& data,
@@ -1343,6 +1301,9 @@ void WebURLLoaderImpl::LoadSynchronously(
blink::WebBlobInfo& downloaded_blob) {
TRACE_EVENT0("loading", "WebURLLoaderImpl::loadSynchronously");
SyncLoadResponse sync_load_response;
+
+ DCHECK(!context_->client());
+ context_->set_client(client);
context_->Start(request, &sync_load_response);
const GURL& final_url = sync_load_response.url;
diff --git a/chromium/content/renderer/loader/web_url_loader_impl.h b/chromium/content/renderer/loader/web_url_loader_impl.h
index 147130d926e..ced62e5a71b 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl.h
+++ b/chromium/content/renderer/loader/web_url_loader_impl.h
@@ -5,22 +5,15 @@
#ifndef CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
#define CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
-#include <vector>
-
-#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/common/frame.mojom.h"
#include "mojo/public/cpp/system/data_pipe.h"
-#include "net/url_request/redirect_info.h"
-#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/platform/web_url_loader.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h"
-#include "url/gurl.h"
namespace base {
class SingleThreadTaskRunner;
@@ -34,24 +27,6 @@ namespace content {
class ResourceDispatcher;
-// PlzNavigate: Used to override parameters of the navigation request.
-struct CONTENT_EXPORT StreamOverrideParameters {
- public:
- StreamOverrideParameters();
- ~StreamOverrideParameters();
-
- GURL stream_url;
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
- network::ResourceResponseHead response;
- std::vector<GURL> redirects;
- std::vector<network::ResourceResponseInfo> redirect_responses;
- std::vector<net::RedirectInfo> redirect_infos;
-
- // Called when this struct is deleted. Used to notify the browser that it can
- // release its associated StreamHandle.
- base::OnceCallback<void(const GURL&)> on_delete;
-};
-
// Default implementation of WebURLLoaderFactory.
class CONTENT_EXPORT WebURLLoaderFactoryImpl
: public blink::WebURLLoaderFactory {
@@ -95,6 +70,7 @@ class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader {
bool report_security_info);
// WebURLLoader methods:
void LoadSynchronously(const blink::WebURLRequest& request,
+ blink::WebURLLoaderClient* client,
blink::WebURLResponse& response,
base::Optional<blink::WebURLError>& error,
blink::WebData& data,
diff --git a/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
index a573dee34d4..e3fd5112703 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -19,9 +19,9 @@
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/weak_wrapper_shared_url_loader_factory.h"
#include "content/public/renderer/fixed_received_data.h"
#include "content/public/renderer/request_peer.h"
+#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/request_extra_data.h"
#include "content/renderer/loader/resource_dispatcher.h"
#include "content/renderer/loader/sync_load_response.h"
@@ -35,6 +35,7 @@
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_response_info.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -77,7 +78,8 @@ class TestResourceDispatcher : public ResourceDispatcher {
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
double timeout,
- blink::mojom::BlobRegistryPtrInfo download_to_blob_registry) override {
+ blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
+ std::unique_ptr<RequestPeer> peer) override {
*response = std::move(sync_load_response_);
}
@@ -91,14 +93,16 @@ class TestResourceDispatcher : public ResourceDispatcher {
std::unique_ptr<RequestPeer> peer,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
- network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ navigation_response_override_params,
base::OnceClosure* continue_navigation_function) override {
EXPECT_FALSE(peer_);
if (sync_load_response_.info.encoded_body_length != -1)
EXPECT_TRUE(is_sync);
peer_ = std::move(peer);
url_ = request->url;
- stream_url_ = request->resource_body_stream_url;
+ navigation_response_override_params_ =
+ std::move(navigation_response_override_params);
return 1;
}
@@ -125,6 +129,11 @@ class TestResourceDispatcher : public ResourceDispatcher {
sync_load_response_ = std::move(sync_load_response);
}
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ TakeNavigationResponseOverrideParams() {
+ return std::move(navigation_response_override_params_);
+ }
+
private:
std::unique_ptr<RequestPeer> peer_;
bool canceled_;
@@ -132,6 +141,8 @@ class TestResourceDispatcher : public ResourceDispatcher {
GURL url_;
GURL stream_url_;
SyncLoadResponse sync_load_response_;
+ std::unique_ptr<NavigationResponseOverrideParameters>
+ navigation_response_override_params_;
DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcher);
};
@@ -165,7 +176,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
: loader_(new WebURLLoaderImpl(
dispatcher,
blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
- base::MakeRefCounted<WeakWrapperSharedURLLoaderFactory>(
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&fake_url_loader_factory_))),
delete_on_receive_redirect_(false),
delete_on_receive_response_(false),
@@ -230,7 +241,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
loader_.reset();
}
- void DidFinishLoading(double finishTime,
+ void DidFinishLoading(base::TimeTicks finishTime,
int64_t totalEncodedDataLength,
int64_t totalEncodedBodyLength,
int64_t totalDecodedBodyLength,
@@ -622,33 +633,32 @@ TEST_F(WebURLLoaderImplTest, FtpDeleteOnFail) {
DoFailRequest();
}
-// PlzNavigate: checks that the stream override parameters provided on
+// Checks that the navigation response override parameters provided on
// navigation commit are properly applied.
TEST_F(WebURLLoaderImplTest, BrowserSideNavigationCommit) {
// Initialize the request and the stream override.
const GURL kNavigationURL = GURL(kTestURL);
- const GURL kStreamURL = GURL("http://bar");
const std::string kMimeType = "text/html";
blink::WebURLRequest request(kNavigationURL);
request.SetFrameType(network::mojom::RequestContextFrameType::kTopLevel);
request.SetRequestContext(blink::WebURLRequest::kRequestContextFrame);
- std::unique_ptr<StreamOverrideParameters> stream_override(
- new StreamOverrideParameters());
- stream_override->stream_url = kStreamURL;
- stream_override->response.mime_type = kMimeType;
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override(
+ new NavigationResponseOverrideParameters());
+ response_override->response.mime_type = kMimeType;
auto extra_data = std::make_unique<RequestExtraData>();
- extra_data->set_stream_override(std::move(stream_override));
+ extra_data->set_navigation_response_override(std::move(response_override));
request.SetExtraData(std::move(extra_data));
client()->loader()->LoadAsynchronously(request, client());
- // The stream url should have been added to the ResourceRequest.
ASSERT_TRUE(peer());
EXPECT_EQ(kNavigationURL, dispatcher()->url());
- EXPECT_EQ(kStreamURL, dispatcher()->stream_url());
-
EXPECT_FALSE(client()->did_receive_response());
- peer()->OnReceivedResponse(network::ResourceResponseInfo());
+
+ response_override = dispatcher()->TakeNavigationResponseOverrideParams();
+ ASSERT_TRUE(response_override);
+ peer()->OnReceivedResponse(response_override->response);
+
EXPECT_TRUE(client()->did_receive_response());
// The response info should have been overriden.
@@ -789,8 +799,8 @@ TEST_F(WebURLLoaderImplTest, SyncLengths) {
base::Optional<int64_t> downloaded_file_length;
blink::WebBlobInfo downloaded_blob;
client()->loader()->LoadSynchronously(
- request, response, error, data, encoded_data_length, encoded_body_length,
- downloaded_file_length, downloaded_blob);
+ request, nullptr, response, error, data, encoded_data_length,
+ encoded_body_length, downloaded_file_length, downloaded_blob);
EXPECT_EQ(kEncodedBodyLength, encoded_body_length);
EXPECT_EQ(kEncodedDataLength, encoded_data_length);
diff --git a/chromium/content/renderer/loader/web_url_request_util.cc b/chromium/content/renderer/loader/web_url_request_util.cc
index 13ff3603eba..9dacb1aad64 100644
--- a/chromium/content/renderer/loader/web_url_request_util.cc
+++ b/chromium/content/renderer/loader/web_url_request_util.cc
@@ -24,8 +24,9 @@
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/blink/public/mojom/blob/blob.mojom.h"
+#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
+#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_data.h"
@@ -296,10 +297,17 @@ int GetLoadFlagsForWebURLRequest(const WebURLRequest& request) {
WebHTTPBody GetWebHTTPBodyForRequestBody(
const network::ResourceRequestBody& input) {
+ return GetWebHTTPBodyForRequestBodyWithBlobPtrs(input, {});
+}
+
+WebHTTPBody GetWebHTTPBodyForRequestBodyWithBlobPtrs(
+ const network::ResourceRequestBody& input,
+ std::vector<blink::mojom::BlobPtrInfo> blob_ptrs) {
WebHTTPBody http_body;
http_body.Initialize();
http_body.SetIdentifier(input.identifier());
http_body.SetContainsPasswordData(input.contains_sensitive_info());
+ auto blob_ptr_iter = blob_ptrs.begin();
for (auto& element : *input.elements()) {
switch (element.type()) {
case network::DataElement::TYPE_BYTES:
@@ -314,12 +322,16 @@ WebHTTPBody GetWebHTTPBodyForRequestBody(
element.expected_modification_time().ToDoubleT());
break;
case network::DataElement::TYPE_BLOB:
- http_body.AppendBlob(WebString::FromASCII(element.blob_uuid()));
+ if (blob_ptrs.empty()) {
+ http_body.AppendBlob(WebString::FromASCII(element.blob_uuid()));
+ } else {
+ DCHECK(blob_ptr_iter != blob_ptrs.end());
+ blink::mojom::BlobPtrInfo& blob = *blob_ptr_iter++;
+ http_body.AppendBlob(WebString::FromASCII(element.blob_uuid()),
+ element.length(), blob.PassHandle());
+ }
break;
case network::DataElement::TYPE_DATA_PIPE: {
- // Append the cloned data pipe to the |http_body|. This might not be
- // needed for all callsites today but it respects the constness of
- // |input|, as opposed to moving the data pipe out of |input|.
http_body.AppendDataPipe(
element.CloneDataPipeGetter().PassInterface().PassHandle());
break;
@@ -334,6 +346,25 @@ WebHTTPBody GetWebHTTPBodyForRequestBody(
return http_body;
}
+std::vector<blink::mojom::BlobPtrInfo> GetBlobPtrsForRequestBody(
+ const network::ResourceRequestBody& input) {
+ std::vector<blink::mojom::BlobPtrInfo> blob_ptrs;
+ blink::mojom::BlobRegistryPtr blob_registry;
+ for (auto& element : *input.elements()) {
+ if (element.type() == network::DataElement::TYPE_BLOB) {
+ blink::mojom::BlobPtrInfo blob_ptr;
+ if (!blob_registry) {
+ blink::Platform::Current()->GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&blob_registry));
+ }
+ blob_registry->GetBlobFromUUID(mojo::MakeRequest(&blob_ptr),
+ element.blob_uuid());
+ blob_ptrs.push_back(std::move(blob_ptr));
+ }
+ }
+ return blob_ptrs;
+}
+
scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebURLRequest(
const WebURLRequest& request) {
scoped_refptr<network::ResourceRequestBody> request_body;
@@ -390,7 +421,8 @@ scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebHTTPBody(
request_body->AppendDataPipe(std::move(data_pipe_getter_ptr));
} else {
- request_body->AppendBlob(element.blob_uuid.Utf8());
+ request_body->AppendBlob(element.blob_uuid.Utf8(),
+ element.blob_length);
}
break;
}
diff --git a/chromium/content/renderer/loader/web_url_request_util.h b/chromium/content/renderer/loader/web_url_request_util.h
index dd42dcb240e..bc85bb64d15 100644
--- a/chromium/content/renderer/loader/web_url_request_util.h
+++ b/chromium/content/renderer/loader/web_url_request_util.h
@@ -13,6 +13,7 @@
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
+#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -40,6 +41,19 @@ int GetLoadFlagsForWebURLRequest(const blink::WebURLRequest& request);
blink::WebHTTPBody GetWebHTTPBodyForRequestBody(
const network::ResourceRequestBody& input);
+// Takes a ResourceRequestBody with additional |blob_ptrs| which corresponds to
+// each Blob entries, and converts into WebHTTPBody.
+// TODO(kinuko): Remove this once Network Service is shipped.
+blink::WebHTTPBody GetWebHTTPBodyForRequestBodyWithBlobPtrs(
+ const network::ResourceRequestBody& input,
+ std::vector<blink::mojom::BlobPtrInfo> blob_ptrs);
+
+// Takes a ResourceRequestBody and gets blob pointers for Blob entries.
+// Used only in non-NetworkService cases but with S13nServiceWorker.
+// TODO(kinuko): Remove this once Network Service is shipped.
+std::vector<blink::mojom::BlobPtrInfo> GetBlobPtrsForRequestBody(
+ const network::ResourceRequestBody& input);
+
// Takes a WebHTTPBody and converts into a ResourceRequestBody.
scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebHTTPBody(
const blink::WebHTTPBody& httpBody);