summaryrefslogtreecommitdiff
path: root/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/loader/resource_dispatcher_host_impl.cc')
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.cc352
1 files changed, 211 insertions, 141 deletions
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
index 8cc50c6f058..4117eae4cdc 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -32,7 +32,7 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
-#include "base/time/time.h"
+#include "base/timer/timer.h"
#include "content/browser/appcache/appcache_interceptor.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/bad_message.h"
@@ -44,7 +44,6 @@
#include "content/browser/frame_host/navigator.h"
#include "content/browser/loader/async_resource_handler.h"
#include "content/browser/loader/async_revalidation_manager.h"
-#include "content/browser/loader/cross_site_resource_handler.h"
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/intercepting_resource_handler.h"
#include "content/browser/loader/loader_delegate.h"
@@ -55,8 +54,10 @@
#include "content/browser/loader/navigation_url_loader_impl_core.h"
#include "content/browser/loader/power_save_block_resource_throttle.h"
#include "content/browser/loader/redirect_to_file_resource_handler.h"
+#include "content/browser/loader/resource_loader.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/loader/resource_scheduler.h"
#include "content/browser/loader/stream_resource_handler.h"
#include "content/browser/loader/sync_resource_handler.h"
#include "content/browser/loader/throttling_resource_handler.h"
@@ -64,6 +65,7 @@
#include "content/browser/resource_context_impl.h"
#include "content/browser/service_worker/foreign_fetch_request_handler.h"
#include "content/browser/service_worker/link_header_support.h"
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_context.h"
@@ -96,10 +98,10 @@
#include "net/base/mime_util.h"
#include "net/base/net_errors.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "net/base/request_priority.h"
#include "net/base/upload_data_stream.h"
#include "net/cert/cert_status_flags.h"
#include "net/cookies/cookie_monster.h"
+#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/ssl/client_cert_store.h"
@@ -113,12 +115,15 @@
#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/file_permission_policy.h"
#include "storage/browser/fileapi/file_system_context.h"
+#include "url/third_party/mozilla/url_parse.h"
#include "url/url_constants.h"
using base::Time;
using base::TimeDelta;
using base::TimeTicks;
using storage::ShareableFileReference;
+using SyncLoadResultCallback =
+ content::ResourceDispatcherHostImpl::SyncLoadResultCallback;
// ----------------------------------------------------------------------------
@@ -221,15 +226,15 @@ bool IsDetachableResourceType(ResourceType type) {
}
// Aborts a request before an URLRequest has actually been created.
-void AbortRequestBeforeItStarts(ResourceMessageFilter* filter,
- IPC::Message* sync_result,
- int request_id,
- mojom::URLLoaderClientPtr url_loader_client) {
- if (sync_result) {
+void AbortRequestBeforeItStarts(
+ ResourceMessageFilter* filter,
+ const SyncLoadResultCallback& sync_result_handler,
+ int request_id,
+ mojom::URLLoaderClientAssociatedPtr url_loader_client) {
+ if (sync_result_handler) {
SyncLoadResult result;
result.error_code = net::ERR_ABORTED;
- ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result, result);
- filter->Send(sync_result);
+ sync_result_handler.Run(&result);
} else {
// Tell the renderer that this request was disallowed.
ResourceRequestCompletionStatus request_complete_data;
@@ -261,9 +266,13 @@ void SetReferrerForRequest(net::URLRequest* request, const Referrer& referrer) {
net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
switch (referrer.policy) {
case blink::WebReferrerPolicyAlways:
+ net_referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER;
+ break;
case blink::WebReferrerPolicyNever:
+ net_referrer_policy = net::URLRequest::NO_REFERRER;
+ break;
case blink::WebReferrerPolicyOrigin:
- net_referrer_policy = net::URLRequest::NEVER_CLEAR_REFERRER;
+ net_referrer_policy = net::URLRequest::ORIGIN;
break;
case blink::WebReferrerPolicyNoReferrerWhenDowngrade:
net_referrer_policy =
@@ -414,6 +423,22 @@ void NotifyForEachFrameFromUI(
base::Passed(std::move(routing_ids))));
}
+// Sends back the result of a synchronous loading result to the renderer through
+// Chrome IPC.
+void HandleSyncLoadResult(base::WeakPtr<ResourceMessageFilter> filter,
+ std::unique_ptr<IPC::Message> sync_result,
+ const SyncLoadResult* result) {
+ if (!filter)
+ return;
+
+ if (result) {
+ ResourceHostMsg_SyncLoad::WriteReplyParams(sync_result.get(), *result);
+ } else {
+ sync_result->set_reply_error();
+ }
+ filter->Send(sync_result.release());
+}
+
} // namespace
ResourceDispatcherHostImpl::LoadInfo::LoadInfo() {}
@@ -728,10 +753,7 @@ bool ResourceDispatcherHostImpl::HandleExternalProtocol(ResourceLoader* loader,
if (job_factory->IsHandledURL(url))
return false;
- return delegate_->HandleExternalProtocol(
- url, info->GetChildID(), info->GetWebContentsGetterForRequest(),
- info->IsMainFrame(), info->GetPageTransition(), info->HasUserGesture(),
- info->GetContext());
+ return delegate_->HandleExternalProtocol(url, info);
}
void ResourceDispatcherHostImpl::DidStartRequest(ResourceLoader* loader) {
@@ -909,7 +931,7 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
}
if (loader->request()->url().SchemeIsCryptographic()) {
- if (loader->request()->url().host() == "www.google.com") {
+ if (loader->request()->url().host_piece() == "www.google.com") {
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.ErrorCodesForHTTPSGoogleMainFrame2",
-loader->request()->status().error());
}
@@ -995,7 +1017,6 @@ bool ResourceDispatcherHostImpl::OnMessageReceived(
IPC_MESSAGE_HANDLER_DELAY_REPLY(ResourceHostMsg_SyncLoad, OnSyncLoad)
IPC_MESSAGE_HANDLER(ResourceHostMsg_ReleaseDownloadedFile,
OnReleaseDownloadedFile)
- IPC_MESSAGE_HANDLER(ResourceHostMsg_DataDownloaded_ACK, OnDataDownloadedACK)
IPC_MESSAGE_HANDLER(ResourceHostMsg_CancelRequest, OnCancelRequest)
IPC_MESSAGE_HANDLER(ResourceHostMsg_DidChangePriority, OnDidChangePriority)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -1009,10 +1030,11 @@ bool ResourceDispatcherHostImpl::OnMessageReceived(
GlobalRequestID id(filter_->child_id(), request_id);
DelegateMap::iterator it = delegate_map_.find(id);
if (it != delegate_map_.end()) {
- base::ObserverList<ResourceMessageDelegate>::Iterator del_it(it->second);
- ResourceMessageDelegate* delegate;
- while (!handled && (delegate = del_it.GetNext()) != NULL) {
- handled = delegate->OnMessageReceived(message);
+ for (auto& delegate : *it->second) {
+ if (delegate.OnMessageReceived(message)) {
+ handled = true;
+ break;
+ }
}
}
@@ -1037,8 +1059,8 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
int routing_id,
int request_id,
const ResourceRequest& request_data,
- mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
- mojom::URLLoaderClientPtr url_loader_client) {
+ mojom::URLLoaderAssociatedRequest mojo_request,
+ mojom::URLLoaderClientAssociatedPtr url_loader_client) {
// TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
@@ -1059,7 +1081,7 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
request_data.render_frame_id,
request_data.url));
}
- BeginRequest(request_id, request_data, NULL, routing_id,
+ BeginRequest(request_id, request_data, SyncLoadResultCallback(), routing_id,
std::move(mojo_request), std::move(url_loader_client));
}
@@ -1074,7 +1096,10 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
void ResourceDispatcherHostImpl::OnSyncLoad(int request_id,
const ResourceRequest& request_data,
IPC::Message* sync_result) {
- BeginRequest(request_id, request_data, sync_result, sync_result->routing_id(),
+ SyncLoadResultCallback callback = base::Bind(
+ &HandleSyncLoadResult, filter_->GetWeakPtr(),
+ base::Passed(WrapUnique(sync_result)));
+ BeginRequest(request_id, request_data, callback, sync_result->routing_id(),
nullptr, nullptr);
}
@@ -1145,11 +1170,8 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
DelegateMap::iterator it = delegate_map_.find(old_request_id);
if (it != delegate_map_.end()) {
// Tell each delegate that the request ID has changed.
- base::ObserverList<ResourceMessageDelegate>::Iterator del_it(it->second);
- ResourceMessageDelegate* delegate;
- while ((delegate = del_it.GetNext()) != NULL) {
- delegate->set_request_id(new_request_id);
- }
+ for (auto& delegate : *it->second)
+ delegate.set_request_id(new_request_id);
// Now store the observer list under the new request ID.
delegate_map_[new_request_id] = delegate_map_[old_request_id];
delegate_map_.erase(old_request_id);
@@ -1173,18 +1195,66 @@ void ResourceDispatcherHostImpl::UpdateRequestForTransfer(
child_id, request_data.service_worker_provider_id);
}
}
+}
+
+void ResourceDispatcherHostImpl::CompleteTransfer(
+ int request_id,
+ const ResourceRequest& request_data,
+ int route_id) {
+ // Caller should ensure that |request_data| is associated with a transfer.
+ DCHECK(request_data.transferred_request_child_id != -1 ||
+ request_data.transferred_request_request_id != -1);
+
+ bool is_navigational_request =
+ request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME ||
+ request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
+ if (!is_navigational_request) {
+ // Transfers apply only to navigational requests - the renderer seems to
+ // have sent bogus IPC data.
+ bad_message::ReceivedBadMessage(
+ filter_, bad_message::RDH_TRANSFERRING_NONNAVIGATIONAL_REQUEST);
+ return;
+ }
- // We should have a CrossSiteResourceHandler to finish the transfer.
- DCHECK(info->cross_site_handler());
+ // Attempt to find a loader associated with the deferred transfer request.
+ LoaderMap::iterator it = pending_loaders_.find(
+ GlobalRequestID(request_data.transferred_request_child_id,
+ request_data.transferred_request_request_id));
+ if (it == pending_loaders_.end()) {
+ // Renderer sent transferred_request_request_id and/or
+ // transferred_request_child_id that doesn't have a corresponding entry on
+ // the browser side.
+ // TODO(lukasza): https://crbug.com/659613: Need to understand the scenario
+ // that can lead here (and then attempt to reintroduce a renderer kill
+ // below).
+ return;
+ }
+ ResourceLoader* pending_loader = it->second.get();
+
+ if (!pending_loader->is_transferring()) {
+ // Renderer sent transferred_request_request_id and/or
+ // transferred_request_child_id that doesn't correspond to an actually
+ // transferring loader on the browser side.
+ base::debug::Alias(pending_loader);
+ bad_message::ReceivedBadMessage(filter_,
+ bad_message::RDH_REQUEST_NOT_TRANSFERRING);
+ return;
+ }
+
+ // If the request is transferring to a new process, we can update our
+ // state and let it resume with its existing ResourceHandlers.
+ UpdateRequestForTransfer(filter_->child_id(), route_id, request_id,
+ request_data, it);
+ pending_loader->CompleteTransfer();
}
void ResourceDispatcherHostImpl::BeginRequest(
int request_id,
const ResourceRequest& request_data,
- IPC::Message* sync_result, // only valid for sync
+ const SyncLoadResultCallback& sync_result_handler, // only valid for sync
int route_id,
- mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
- mojom::URLLoaderClientPtr url_loader_client) {
+ mojom::URLLoaderAssociatedRequest mojo_request,
+ mojom::URLLoaderClientAssociatedPtr url_loader_client) {
int process_type = filter_->process_type();
int child_id = filter_->child_id();
@@ -1222,24 +1292,12 @@ void ResourceDispatcherHostImpl::BeginRequest(
// If the request that's coming in is being transferred from another process,
// we want to reuse and resume the old loader rather than start a new one.
- LoaderMap::iterator it = pending_loaders_.find(
- GlobalRequestID(request_data.transferred_request_child_id,
- request_data.transferred_request_request_id));
- if (it != pending_loaders_.end()) {
+ if (request_data.transferred_request_child_id != -1 ||
+ request_data.transferred_request_request_id != -1) {
// TODO(yhirano): Make mojo work for this case.
DCHECK(!url_loader_client);
- // If the request is transferring to a new process, we can update our
- // state and let it resume with its existing ResourceHandlers.
- if (it->second->is_transferring()) {
- ResourceLoader* deferred_loader = it->second.get();
- UpdateRequestForTransfer(child_id, route_id, request_id,
- request_data, it);
- deferred_loader->CompleteTransfer();
- } else {
- bad_message::ReceivedBadMessage(
- filter_, bad_message::RDH_REQUEST_NOT_TRANSFERRING);
- }
+ CompleteTransfer(request_id, request_data, route_id);
return;
}
@@ -1256,7 +1314,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
if (is_shutdown_ ||
!ShouldServiceRequest(process_type, child_id, request_data, headers,
filter_, resource_context)) {
- AbortRequestBeforeItStarts(filter_, sync_result, request_id,
+ AbortRequestBeforeItStarts(filter_, sync_result_handler, request_id,
std::move(url_loader_client));
return;
}
@@ -1281,33 +1339,33 @@ void ResourceDispatcherHostImpl::BeginRequest(
it.name(), it.value(), child_id, resource_context,
base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest,
base::Unretained(this), request_id, request_data,
- sync_result, route_id, headers,
+ sync_result_handler, route_id, headers,
base::Passed(std::move(mojo_request)),
base::Passed(std::move(url_loader_client))));
return;
}
}
}
- ContinuePendingBeginRequest(request_id, request_data, sync_result, route_id,
- headers, std::move(mojo_request),
+ ContinuePendingBeginRequest(request_id, request_data, sync_result_handler,
+ route_id, headers, std::move(mojo_request),
std::move(url_loader_client), true, 0);
}
void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
int request_id,
const ResourceRequest& request_data,
- IPC::Message* sync_result, // only valid for sync
+ const SyncLoadResultCallback& sync_result_handler, // only valid for sync
int route_id,
const net::HttpRequestHeaders& headers,
- mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
- mojom::URLLoaderClientPtr url_loader_client,
+ mojom::URLLoaderAssociatedRequest mojo_request,
+ mojom::URLLoaderClientAssociatedPtr url_loader_client,
bool continue_request,
int error_code) {
if (!continue_request) {
// TODO(ananta): Find a way to specify the right error code here. Passing
// in a non-content error code is not safe.
bad_message::ReceivedBadMessage(filter_, bad_message::RDH_ILLEGAL_ORIGIN);
- AbortRequestBeforeItStarts(filter_, sync_result, request_id,
+ AbortRequestBeforeItStarts(filter_, sync_result_handler, request_id,
std::move(url_loader_client));
return;
}
@@ -1330,7 +1388,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
request_data.url,
request_data.resource_type,
resource_context)) {
- AbortRequestBeforeItStarts(filter_, sync_result, request_id,
+ AbortRequestBeforeItStarts(filter_, sync_result_handler, request_id,
std::move(url_loader_client));
return;
}
@@ -1352,6 +1410,12 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
new_request->set_first_party_for_cookies(
request_data.first_party_for_cookies);
+
+ // The initiator should normally be present, unless this is a navigation in a
+ // top-level frame. It may be null for some top-level navigations (eg:
+ // browser-initiated ones).
+ DCHECK(request_data.request_initiator.has_value() ||
+ request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME);
new_request->set_initiator(request_data.request_initiator);
if (request_data.originated_from_service_worker) {
@@ -1403,7 +1467,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
bool allow_download = request_data.allow_download &&
IsResourceTypeFrame(request_data.resource_type);
bool do_not_prompt_for_login = request_data.do_not_prompt_for_login;
- bool is_sync_load = sync_result != NULL;
+ bool is_sync_load = !!sync_result_handler;
// Raw headers are sensitive, as they include Cookie/Set-Cookie, so only
// allow requesting them if requester has ReadRawCookies permission.
@@ -1515,8 +1579,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
request_data.should_reset_appcache);
std::unique_ptr<ResourceHandler> handler(CreateResourceHandler(
- new_request.get(), request_data, sync_result, route_id, process_type,
- child_id, resource_context, std::move(mojo_request),
+ new_request.get(), request_data, sync_result_handler, route_id,
+ process_type, child_id, resource_context, std::move(mojo_request),
std::move(url_loader_client)));
if (handler)
@@ -1527,20 +1591,20 @@ std::unique_ptr<ResourceHandler>
ResourceDispatcherHostImpl::CreateResourceHandler(
net::URLRequest* request,
const ResourceRequest& request_data,
- IPC::Message* sync_result,
+ const SyncLoadResultCallback& sync_result_handler,
int route_id,
int process_type,
int child_id,
ResourceContext* resource_context,
- mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
- mojom::URLLoaderClientPtr url_loader_client) {
+ mojom::URLLoaderAssociatedRequest mojo_request,
+ mojom::URLLoaderClientAssociatedPtr url_loader_client) {
// TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed.
tracked_objects::ScopedTracker tracking_profile(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"456331 ResourceDispatcherHostImpl::CreateResourceHandler"));
// Construct the IPC resource handler.
std::unique_ptr<ResourceHandler> handler;
- if (sync_result) {
+ if (sync_result_handler) {
// download_to_file is not supported for synchronous requests.
if (request_data.download_to_file) {
bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD);
@@ -1549,7 +1613,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
DCHECK(!mojo_request.is_pending());
DCHECK(!url_loader_client);
- handler.reset(new SyncResourceHandler(request, sync_result, this));
+ handler.reset(new SyncResourceHandler(request, sync_result_handler, this));
} else {
if (mojo_request.is_pending()) {
handler.reset(new MojoAsyncResourceHandler(request, this,
@@ -1569,8 +1633,9 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
bool start_detached = request_data.download_to_network_cache_only;
// Prefetches and <a ping> requests outlive their child process.
- if (!sync_result && (start_detached ||
- IsDetachableResourceType(request_data.resource_type))) {
+ if (!sync_result_handler &&
+ (start_detached ||
+ IsDetachableResourceType(request_data.resource_type))) {
std::unique_ptr<DetachableResourceHandler> detachable_handler =
base::MakeUnique<DetachableResourceHandler>(
request,
@@ -1581,28 +1646,6 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
handler = std::move(detachable_handler);
}
- // PlzNavigate: If using --enable-browser-side-navigation, the
- // CrossSiteResourceHandler is not needed. This codepath is not used for the
- // actual navigation request, but only the subsequent blob URL load. This does
- // not require request transfers.
- if (!IsBrowserSideNavigationEnabled()) {
- // Install a CrossSiteResourceHandler for all main frame requests. This will
- // check whether a transfer is required and, if so, pause for the UI thread
- // to drive the transfer.
- bool is_swappable_navigation =
- request_data.resource_type == RESOURCE_TYPE_MAIN_FRAME;
- // If out-of-process iframes are possible, then all subframe requests need
- // to go through the CrossSiteResourceHandler to enforce the site isolation
- // policy.
- if (!is_swappable_navigation &&
- SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
- is_swappable_navigation =
- request_data.resource_type == RESOURCE_TYPE_SUB_FRAME;
- }
- if (is_swappable_navigation && process_type == PROCESS_TYPE_RENDERER)
- handler.reset(new CrossSiteResourceHandler(std::move(handler), request));
- }
-
return AddStandardHandlers(
request, request_data.resource_type, resource_context,
request_data.fetch_request_context_type, filter_->appcache_service(),
@@ -1725,10 +1768,6 @@ void ResourceDispatcherHostImpl::OnDidChangePriority(
intra_priority_value);
}
-void ResourceDispatcherHostImpl::OnDataDownloadedACK(int request_id) {
- // TODO(michaeln): maybe throttle DataDownloaded messages
-}
-
void ResourceDispatcherHostImpl::RegisterDownloadedTempFile(
int child_id, int request_id, const base::FilePath& file_path) {
scoped_refptr<ShareableFileReference> reference =
@@ -1770,26 +1809,8 @@ bool ResourceDispatcherHostImpl::Send(IPC::Message* message) {
return false;
}
-// Note that this cancel is subtly different from the other
-// CancelRequest methods in this file, which also tear down the loader.
void ResourceDispatcherHostImpl::OnCancelRequest(int request_id) {
- int child_id = filter_->child_id();
-
- // When the old renderer dies, it sends a message to us to cancel its
- // requests.
- if (IsTransferredNavigation(GlobalRequestID(child_id, request_id)))
- return;
-
- ResourceLoader* loader = GetLoader(child_id, request_id);
-
- // It is possible that the request has been completed and removed from the
- // loader queue but the client has not processed the request completed message
- // before issuing a cancel. This happens frequently for beacons which are
- // canceled in the response received handler.
- if (!loader)
- return;
-
- loader->CancelRequest(true);
+ CancelRequestFromRenderer(GlobalRequestID(filter_->child_id(), request_id));
}
ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
@@ -1799,17 +1820,12 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
bool download,
ResourceContext* context) {
return new ResourceRequestInfoImpl(
- PROCESS_TYPE_RENDERER,
- child_id,
- render_view_route_id,
+ PROCESS_TYPE_RENDERER, child_id, render_view_route_id,
-1, // frame_tree_node_id
- 0,
- request_id_,
- render_frame_route_id,
- false, // is_main_frame
- false, // parent_is_main_frame
- RESOURCE_TYPE_SUB_RESOURCE,
- ui::PAGE_TRANSITION_LINK,
+ 0, MakeRequestID(), render_frame_route_id,
+ false, // is_main_frame
+ false, // parent_is_main_frame
+ RESOURCE_TYPE_SUB_RESOURCE, ui::PAGE_TRANSITION_LINK,
false, // should_replace_current_entry
download, // is_download
false, // is_stream
@@ -1818,8 +1834,7 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
false, // enable_load_timing
false, // enable_upload_progress
false, // do_not_prompt_for_login
- blink::WebReferrerPolicyDefault,
- blink::WebPageVisibilityStateVisible,
+ blink::WebReferrerPolicyDefault, blink::WebPageVisibilityStateVisible,
context,
base::WeakPtr<ResourceMessageFilter>(), // filter
false, // report_raw_headers
@@ -1848,8 +1863,8 @@ void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id,
void ResourceDispatcherHostImpl::MarkAsTransferredNavigation(
const GlobalRequestID& id,
- const scoped_refptr<ResourceResponse>& response) {
- GetLoader(id)->MarkAsTransferring(response);
+ const base::Closure& on_transfer_complete_callback) {
+ GetLoader(id)->MarkAsTransferring(on_transfer_complete_callback);
}
void ResourceDispatcherHostImpl::CancelTransferringNavigation(
@@ -2083,7 +2098,21 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
ResourceType resource_type = info.is_main_frame ?
RESOURCE_TYPE_MAIN_FRAME : RESOURCE_TYPE_SUB_FRAME;
- if (is_shutdown_ ||
+ // Do not allow browser plugin guests to navigate to non-web URLs, since they
+ // cannot swap processes or grant bindings. Do not check external protocols
+ // here because they're checked in
+ // ChromeResourceDispatcherHostDelegate::HandleExternalProtocol.
+ ChildProcessSecurityPolicyImpl* policy =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ bool is_external_protocol =
+ !resource_context->GetRequestContext()->job_factory()->IsHandledURL(
+ info.common_params.url);
+ bool non_web_url_in_guest =
+ info.is_for_guests_only &&
+ !policy->IsWebSafeScheme(info.common_params.url.scheme()) &&
+ !is_external_protocol;
+
+ if (is_shutdown_ || non_web_url_in_guest ||
// TODO(davidben): Check ShouldServiceRequest here. This is important; it
// needs to be checked relative to the child that /requested/ the
// navigation. It's where file upload checks, etc., come in.
@@ -2148,8 +2177,6 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get()));
}
- request_id_--;
-
// Make extra info and read footer (contains request ID).
//
// TODO(davidben): Associate the request with the FrameTreeNode and/or tab so
@@ -2160,7 +2187,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
-1, // route_id
info.frame_tree_node_id,
-1, // request_data.origin_pid,
- request_id_,
+ MakeRequestID(),
-1, // request_data.render_frame_id,
info.is_main_frame, info.parent_is_main_frame, resource_type,
info.common_params.transition,
@@ -2179,7 +2206,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
// same mechanism as the cookie one.
blink::WebPageVisibilityStateVisible, resource_context,
base::WeakPtr<ResourceMessageFilter>(), // filter
- false, // request_data.report_raw_headers
+ info.report_raw_headers,
true, // is_async
IsUsingLoFi(info.common_params.lofi_state, delegate_, *new_request,
resource_context, info.is_main_frame),
@@ -2197,6 +2224,11 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
false); // initiated_in_secure_context
extra_info->set_navigation_ui_data(std::move(navigation_ui_data));
+ if (service_worker_handle_core) {
+ extra_info->set_service_worker_context(
+ service_worker_handle_core->context_wrapper());
+ }
+
// Request takes ownership.
extra_info->AssociateWithRequest(new_request.get());
@@ -2255,8 +2287,8 @@ void ResourceDispatcherHostImpl::OnRequestResourceWithMojo(
int routing_id,
int request_id,
const ResourceRequest& request,
- mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
- mojom::URLLoaderClientPtr url_loader_client,
+ mojom::URLLoaderAssociatedRequest mojo_request,
+ mojom::URLLoaderClientAssociatedPtr url_loader_client,
ResourceMessageFilter* filter) {
filter_ = filter;
OnRequestResourceInternal(routing_id, request_id, request,
@@ -2265,16 +2297,32 @@ void ResourceDispatcherHostImpl::OnRequestResourceWithMojo(
filter_ = nullptr;
}
+void ResourceDispatcherHostImpl::OnSyncLoadWithMojo(
+ int routing_id,
+ int request_id,
+ const ResourceRequest& request_data,
+ ResourceMessageFilter* filter,
+ const SyncLoadResultCallback& result_handler) {
+ filter_ = filter;
+ BeginRequest(request_id, request_data, result_handler, routing_id,
+ nullptr, nullptr);
+ filter_ = nullptr;
+}
+
// static
int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
net::URLRequest* request) {
// The following fields should be a minor size contribution (experimentally
// on the order of 100). However since they are variable length, it could
// in theory be a sizeable contribution.
- int strings_cost = request->extra_request_headers().ToString().size() +
- request->original_url().spec().size() +
- request->referrer().size() +
- request->method().size();
+ int strings_cost = 0;
+ for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers());
+ it.GetNext();) {
+ strings_cost += it.name().length() + it.value().length();
+ }
+ strings_cost +=
+ request->original_url().parsed_for_possibly_invalid_spec().Length() +
+ request->referrer().size() + request->method().size();
// Note that this expression will typically be dominated by:
// |kAvgBytesPerOutstandingRequest|.
@@ -2345,8 +2393,6 @@ void ResourceDispatcherHostImpl::InitializeURLRequest(
SetReferrerForRequest(request, referrer);
- request_id_--;
-
ResourceRequestInfoImpl* info =
CreateRequestInfo(render_process_host_id, render_view_routing_id,
render_frame_routing_id, is_download, context);
@@ -2392,6 +2438,30 @@ void ResourceDispatcherHostImpl::BeginURLRequest(
BeginRequestInternal(std::move(request), std::move(handler));
}
+int ResourceDispatcherHostImpl::MakeRequestID() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return --request_id_;
+}
+
+void ResourceDispatcherHostImpl::CancelRequestFromRenderer(
+ GlobalRequestID request_id) {
+ // When the old renderer dies, it sends a message to us to cancel its
+ // requests.
+ if (IsTransferredNavigation(request_id))
+ return;
+
+ ResourceLoader* loader = GetLoader(request_id);
+
+ // It is possible that the request has been completed and removed from the
+ // loader queue but the client has not processed the request completed message
+ // before issuing a cancel. This happens frequently for beacons which are
+ // canceled in the response received handler.
+ if (!loader)
+ return;
+
+ loader->CancelRequest(true);
+}
+
void ResourceDispatcherHostImpl::StartLoading(
ResourceRequestInfoImpl* info,
std::unique_ptr<ResourceLoader> loader) {