Index: content/browser/service_worker/service_worker_request_handler.cc |
diff --git a/content/browser/service_worker/service_worker_request_handler.cc b/content/browser/service_worker/service_worker_request_handler.cc |
index 6d7d04b2e0a1b99a9101916faee3f4dd1612a9fb..27f3dea63e844ce6c03c779f865cc5f4c64bdc2b 100644 |
--- a/content/browser/service_worker/service_worker_request_handler.cc |
+++ b/content/browser/service_worker/service_worker_request_handler.cc |
@@ -6,8 +6,10 @@ |
#include <string> |
+#include "base/command_line.h" |
#include "content/browser/service_worker/service_worker_context_core.h" |
#include "content/browser/service_worker/service_worker_context_wrapper.h" |
+#include "content/browser/service_worker/service_worker_navigation_handle_core.h" |
#include "content/browser/service_worker/service_worker_provider_host.h" |
#include "content/browser/service_worker/service_worker_registration.h" |
#include "content/browser/service_worker/service_worker_url_request_job.h" |
@@ -15,7 +17,10 @@ |
#include "content/common/service_worker/service_worker_types.h" |
#include "content/common/service_worker/service_worker_utils.h" |
#include "content/public/browser/resource_context.h" |
+#include "content/public/common/child_process_host.h" |
+#include "content/public/common/content_switches.h" |
#include "content/public/common/origin_util.h" |
+#include "ipc/ipc_message.h" |
#include "net/base/net_util.h" |
#include "net/url_request/url_request.h" |
#include "net/url_request/url_request_interceptor.h" |
@@ -49,8 +54,92 @@ class ServiceWorkerRequestInterceptor |
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRequestInterceptor); |
}; |
+void FinalizeHandlerInitialization( |
+ net::URLRequest* request, |
+ ServiceWorkerProviderHost* provider_host, |
+ storage::BlobStorageContext* blob_storage_context, |
+ bool skip_service_worker, |
+ FetchRequestMode request_mode, |
+ FetchCredentialsMode credentials_mode, |
+ FetchRedirectMode redirect_mode, |
+ ResourceType resource_type, |
+ RequestContextType request_context_type, |
+ RequestContextFrameType frame_type, |
+ scoped_refptr<ResourceRequestBody> body) { |
+ if (skip_service_worker) { |
+ // TODO(horo): Does this work properly for PlzNavigate? |
+ if (ServiceWorkerUtils::IsMainResourceType(resource_type)) { |
+ provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url())); |
+ provider_host->SetTopmostFrameUrl(request->first_party_for_cookies()); |
+ // A page load with skip_service_worker should be triggered by |
+ // shift-reload, so retain all live matching registrations. |
+ provider_host->AddAllMatchingRegistrations(); |
+ } |
+ return; |
+ } |
+ |
+ scoped_ptr<ServiceWorkerRequestHandler> handler( |
+ provider_host->CreateRequestHandler( |
+ request_mode, credentials_mode, redirect_mode, resource_type, |
+ request_context_type, frame_type, blob_storage_context->AsWeakPtr(), |
+ body)); |
+ if (!handler) |
+ return; |
+ |
+ request->SetUserData(&kUserDataKey, handler.release()); |
+} |
+ |
} // namespace |
+// PlzNavigate |
+void ServiceWorkerRequestHandler::InitializeForNavigation( |
+ net::URLRequest* request, |
+ ServiceWorkerNavigationHandleCore* navigation_handle_core, |
+ storage::BlobStorageContext* blob_storage_context, |
+ bool skip_service_worker, |
+ ResourceType resource_type, |
+ RequestContextType request_context_type, |
+ RequestContextFrameType frame_type, |
+ scoped_refptr<ResourceRequestBody> body) { |
+ CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
+ |
+ // Only create a handler when there is a ServiceWorkerNavigationHandlerCore |
+ // to take ownership of a pre-created SeviceWorkerProviderHost. |
+ if (!navigation_handle_core) |
+ return; |
+ |
+ // Create the handler even for insecure HTTP since it's used in the |
+ // case of redirect to HTTPS. |
+ if (!request->url().SchemeIsHTTPOrHTTPS() && |
+ !OriginCanAccessServiceWorkers(request->url())) { |
+ return; |
+ } |
+ |
+ if (!navigation_handle_core->context_wrapper() || |
+ !navigation_handle_core->context_wrapper()->context()) { |
+ return; |
+ } |
+ |
+ // Initialize the SWProviderHost. |
+ scoped_ptr<ServiceWorkerProviderHost> provider_host = |
+ ServiceWorkerProviderHost::PreCreateNavigationHost( |
+ navigation_handle_core->context_wrapper()->context()->AsWeakPtr()); |
+ |
+ FinalizeHandlerInitialization( |
+ request, provider_host.get(), blob_storage_context, skip_service_worker, |
+ FETCH_REQUEST_MODE_SAME_ORIGIN, FETCH_CREDENTIALS_MODE_INCLUDE, |
+ FetchRedirectMode::MANUAL_MODE, resource_type, request_context_type, |
+ frame_type, body); |
+ |
+ // Transfer ownership to the ServiceWorkerNavigationHandleCore. |
+ // In the case of a successful navigation, the SWProviderHost will be |
+ // transferred to its "final" destination in the OnProviderCreated handler. If |
+ // the navigation fails, it will be destroyed along with the |
+ // ServiceWorkerNavigationHandleCore. |
+ navigation_handle_core->DidPreCreateProviderHost(provider_host.Pass()); |
+} |
+ |
void ServiceWorkerRequestHandler::InitializeHandler( |
net::URLRequest* request, |
ServiceWorkerContextWrapper* context_wrapper, |
@@ -82,26 +171,10 @@ void ServiceWorkerRequestHandler::InitializeHandler( |
if (!provider_host || !provider_host->IsContextAlive()) |
return; |
- if (skip_service_worker) { |
- if (ServiceWorkerUtils::IsMainResourceType(resource_type)) { |
- provider_host->SetDocumentUrl(net::SimplifyUrlForRequest(request->url())); |
- provider_host->SetTopmostFrameUrl(request->first_party_for_cookies()); |
- // A page load with skip_service_worker should be triggered by |
- // shift-reload, so retain all live matching registrations. |
- provider_host->AddAllMatchingRegistrations(); |
- } |
- return; |
- } |
- |
- scoped_ptr<ServiceWorkerRequestHandler> handler( |
- provider_host->CreateRequestHandler( |
- request_mode, credentials_mode, redirect_mode, resource_type, |
- request_context_type, frame_type, blob_storage_context->AsWeakPtr(), |
- body)); |
- if (!handler) |
- return; |
- |
- request->SetUserData(&kUserDataKey, handler.release()); |
+ FinalizeHandlerInitialization(request, provider_host, blob_storage_context, |
+ skip_service_worker, request_mode, |
+ credentials_mode, redirect_mode, resource_type, |
+ request_context_type, frame_type, body); |
} |
ServiceWorkerRequestHandler* ServiceWorkerRequestHandler::GetHandler( |
@@ -128,30 +201,33 @@ bool ServiceWorkerRequestHandler::IsControlledByServiceWorker( |
void ServiceWorkerRequestHandler::PrepareForCrossSiteTransfer( |
int old_process_id) { |
+ CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
if (!provider_host_ || !context_) |
return; |
old_process_id_ = old_process_id; |
old_provider_id_ = provider_host_->provider_id(); |
- host_for_cross_site_transfer_ = |
- context_->TransferProviderHostOut(old_process_id, |
- provider_host_->provider_id()); |
+ host_for_cross_site_transfer_ = context_->TransferProviderHostOut( |
+ old_process_id, provider_host_->provider_id()); |
DCHECK_EQ(provider_host_.get(), host_for_cross_site_transfer_.get()); |
} |
void ServiceWorkerRequestHandler::CompleteCrossSiteTransfer( |
int new_process_id, int new_provider_id) { |
+ CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
if (!host_for_cross_site_transfer_.get() || !context_) |
return; |
DCHECK_EQ(provider_host_.get(), host_for_cross_site_transfer_.get()); |
- context_->TransferProviderHostIn( |
- new_process_id, |
- new_provider_id, |
- host_for_cross_site_transfer_.Pass()); |
+ context_->TransferProviderHostIn(new_process_id, new_provider_id, |
+ host_for_cross_site_transfer_.Pass()); |
DCHECK_EQ(provider_host_->provider_id(), new_provider_id); |
} |
void ServiceWorkerRequestHandler::MaybeCompleteCrossSiteTransferInOldProcess( |
int old_process_id) { |
+ CHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
if (!host_for_cross_site_transfer_.get() || !context_ || |
old_process_id_ != old_process_id) { |
return; |