Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: content/browser/service_worker/service_worker_controllee_request_handler.cc

Issue 2843043002: network service: Create URLLoader for service worker navigation case
Patch Set: . Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_controllee_request_handler.cc
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 76e9c2d3139b242ea1acf4b0bc601f4edd6c3a0c..05380d909c5092d62e93a3337f4c863226fff542 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -25,6 +25,7 @@
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/resource_response_info.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/load_flags.h"
#include "net/base/url_util.h"
#include "net/url_request/url_request.h"
@@ -32,10 +33,98 @@
namespace content {
+// Helper to support both a URLRequestJob and a URLLoaderFactory to support
+// running with and without --enable-network-service.
+class ServiceWorkerControlleeRequestHandler::JobWrapper {
+ public:
+ explicit JobWrapper(base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job)
+ : url_request_job_(std::move(url_request_job)), factory_(nullptr) {}
+
+ // --enable-network-service.
+ explicit JobWrapper(ServiceWorkerControlleeURLLoaderFactory* factory)
+ : factory_(factory) {}
+
+ void FallbackToNetwork() {
+ if (factory_) {
+ factory_->FallbackToNetwork();
+ } else {
+ url_request_job_->FallbackToNetwork();
+ }
+ }
+
+ bool ShouldFallbackToNetwork() {
+ if (factory_) {
+ return factory_->ShouldFallbackToNetwork();
+ } else {
+ return url_request_job_->ShouldFallbackToNetwork();
+ }
+ }
+
+ ui::PageTransition GetPageTransition() {
+ if (factory_) {
+ return factory_->GetPageTransition();
+ } else {
+ const ResourceRequestInfo* info =
+ ResourceRequestInfo::ForRequest(url_request_job_->request());
+ // ResourceRequestInfo may not be set in some tests.
+ if (!info)
+ return ui::PAGE_TRANSITION_LINK;
+ return info->GetPageTransition();
+ }
+ }
+
+ size_t GetURLChainSize() const {
+ if (factory_) {
+ return factory_->GetURLChainSize();
+ } else {
+ return url_request_job_->request()->url_chain().size();
+ }
+ }
+
+ void ForwardToServiceWorker() {
+ if (factory_) {
+ factory_->ForwardToServiceWorker();
+ } else {
+ url_request_job_->ForwardToServiceWorker();
+ }
+ }
+
+ void FallbackToNetworkOrRenderer() {
+ if (factory_) {
+ factory_->FallbackToNetworkOrRenderer();
+ } else {
+ url_request_job_->FallbackToNetworkOrRenderer();
+ }
+ }
+
+ void FailDueToLostController() {
+ if (factory_) {
+ factory_->FailDueToLostController();
+ } else {
+ url_request_job_->FailDueToLostController();
+ }
+ }
+
+ bool WasCanceled() const {
+ if (factory_) {
+ return factory_->WasCanceled();
+ } else {
+ return !url_request_job_;
+ }
+ }
+
+ private:
+ base::WeakPtr<ServiceWorkerURLRequestJob> url_request_job_;
+ ServiceWorkerControlleeURLLoaderFactory* factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(JobWrapper);
+};
+
namespace {
-bool MaybeForwardToServiceWorker(ServiceWorkerURLRequestJob* job,
- const ServiceWorkerVersion* version) {
+bool MaybeForwardToServiceWorker(
+ ServiceWorkerControlleeRequestHandler::JobWrapper* job,
+ const ServiceWorkerVersion* version) {
DCHECK(job);
DCHECK(version);
DCHECK_NE(version->fetch_handler_existence(),
@@ -50,14 +139,6 @@ bool MaybeForwardToServiceWorker(ServiceWorkerURLRequestJob* job,
return false;
}
-ui::PageTransition GetPageTransition(net::URLRequest* request) {
- const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
- // ResourceRequestInfo may not be set in some tests.
- if (!info)
- return ui::PAGE_TRANSITION_LINK;
- return info->GetPageTransition();
-}
-
} // namespace
ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
@@ -70,7 +151,8 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
ResourceType resource_type,
RequestContextType request_context_type,
RequestContextFrameType frame_type,
- scoped_refptr<ResourceRequestBodyImpl> body)
+ scoped_refptr<ResourceRequestBodyImpl> body,
+ NetworkFallbackCallback network_fallback_callback)
: ServiceWorkerRequestHandler(context,
provider_host,
blob_storage_context,
@@ -86,6 +168,7 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
body_(body),
force_update_started_(false),
use_network_(false),
+ network_fallback_callback_(network_fallback_callback),
weak_factory_(this) {}
ServiceWorkerControlleeRequestHandler::
@@ -140,12 +223,12 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
credentials_mode_, redirect_mode_, resource_type_,
request_context_type_, frame_type_, body_,
ServiceWorkerFetchType::FETCH, base::nullopt, this));
- job_ = job->GetWeakPtr();
+ job_ = base::MakeUnique<JobWrapper>(job->GetWeakPtr());
resource_context_ = resource_context;
if (is_main_resource_load_)
- PrepareForMainResource(request);
+ PrepareForMainResource(request->url(), request->first_party_for_cookies());
else
PrepareForSubResource();
@@ -166,16 +249,85 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
return job.release();
}
+mojom::URLLoaderFactoryPtrInfo
+ServiceWorkerControlleeRequestHandler::MaybeGetURLLoaderFactory(
+ const ResourceRequest& request,
+ ResourceContext* resource_context,
+ std::unique_ptr<ServiceWorkerRequestHandler> request_handler) {
+ ClearJob();
+ // TODO(scottmg):
+ // ServiceWorkerResponseInfo::ResetDataForRequest(request);
+
+ if (!context_ || !provider_host_) {
+ // We can't do anything other than to fall back to network.
+ return mojom::URLLoaderFactoryPtrInfo();
+ }
+
+ DCHECK(is_main_resource_load_);
+
+ // This may get called multiple times for original and redirect requests:
+ // A. original request case: use_network_ is false, no previous location info.
+ // B. redirect or restarted request case:
+ // a) use_network_ is false if the previous location was forwarded to SW.
+ // b) use_network_ is false if the previous location was fallback.
+ // c) use_network_ is true if additional restart was required to fall back.
+
+ // Fall back to network. (Case B-c)
+ if (use_network_) {
+ // Once a subresource request has fallen back to the network once, it will
+ // never be handled by a service worker. This is not true of main frame
+ // requests.
+ if (is_main_resource_load_)
+ use_network_ = false;
+ return mojom::URLLoaderFactoryPtrInfo();
+ }
+
+ mojom::URLLoaderFactoryPtr url_loader_factory;
+ auto factory_impl = base::MakeUnique<ServiceWorkerControlleeURLLoaderFactory>(
+ std::move(request_handler), provider_host_->client_uuid(),
+ blob_storage_context_, resource_context, request_mode_, credentials_mode_,
+ redirect_mode_, resource_type_, request_context_type_, frame_type_, body_,
+ ServiceWorkerFetchType::FETCH, base::nullopt, this,
+ network_fallback_callback_);
+ auto* factory = factory_impl.get();
+ mojo::MakeStrongBinding(std::move(factory_impl),
+ mojo::MakeRequest(&url_loader_factory));
+
+ // It's for original request (A) or redirect case (B-a or B-b).
+ job_ = base::MakeUnique<JobWrapper>(factory);
+
+ resource_context_ = resource_context;
+
+ if (is_main_resource_load_)
+ PrepareForMainResource(request.url, request.first_party_for_cookies);
+
+ if (job_->ShouldFallbackToNetwork()) {
+ // If we know we can fallback to network at this point (in case
+ // the storage lookup returned immediately), just destroy the job and return
+ // NULL here to fallback to network.
+
+ // If this is a subresource request, all subsequent requests should also use
+ // the network.
+ if (!is_main_resource_load_)
+ use_network_ = true;
+
+ ClearJob();
+ return mojom::URLLoaderFactoryPtrInfo();
+ }
+
+ return url_loader_factory.PassInterface();
+}
+
void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
- const net::URLRequest* request) {
+ const GURL& url,
+ const GURL& first_party_for_cookies) {
DCHECK(job_.get());
DCHECK(context_);
DCHECK(provider_host_);
TRACE_EVENT_ASYNC_BEGIN1(
"ServiceWorker",
"ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- job_.get(),
- "URL", request->url().spec());
+ job_.get(), "URL", url.spec());
// The corresponding provider_host may already have associated a registration
// in redirect case, unassociate it now.
provider_host_->DisassociateRegistration();
@@ -184,9 +336,9 @@ void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
// registration while we're finding an existing registration.
provider_host_->SetAllowAssociation(false);
- stripped_url_ = net::SimplifyUrlForRequest(request->url());
+ stripped_url_ = net::SimplifyUrlForRequest(url);
provider_host_->SetDocumentUrl(stripped_url_);
- provider_host_->SetTopmostFrameUrl(request->first_party_for_cookies());
+ provider_host_->SetTopmostFrameUrl(first_party_for_cookies);
context_->storage()->FindRegistrationForDocument(
stripped_url_, base::Bind(&self::DidLookupRegistrationForMainResource,
weak_factory_.GetWeakPtr()));
@@ -197,7 +349,7 @@ void ServiceWorkerControlleeRequestHandler::
ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
// The job may have been canceled and then destroyed before this was invoked.
- if (!job_)
+ if (job_->WasCanceled())
return;
const bool need_to_update = !force_update_started_ && registration &&
@@ -312,7 +464,7 @@ void ServiceWorkerControlleeRequestHandler::
ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN);
ServiceWorkerMetrics::CountControlledPageLoad(
active_version->site_for_uma(), stripped_url_, is_main_frame_load_,
- GetPageTransition(job_->request()), job_->request()->url_chain().size());
+ job_->GetPageTransition(), job_->GetURLChainSize());
bool is_forwarded =
MaybeForwardToServiceWorker(job_.get(), active_version.get());
@@ -329,7 +481,7 @@ void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged(
ServiceWorkerRegistration* registration,
ServiceWorkerVersion* version) {
// The job may have been canceled and then destroyed before this was invoked.
- if (!job_)
+ if (job_->WasCanceled())
return;
if (provider_host_)
@@ -345,7 +497,7 @@ void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged(
ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN);
ServiceWorkerMetrics::CountControlledPageLoad(
version->site_for_uma(), stripped_url_, is_main_frame_load_,
- GetPageTransition(job_->request()), job_->request()->url_chain().size());
+ job_->GetPageTransition(), job_->GetURLChainSize());
provider_host_->AssociateRegistration(registration,
false /* notify_controllerchange */);
@@ -361,7 +513,7 @@ void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
DCHECK(force_update_started_);
// The job may have been canceled and then destroyed before this was invoked.
- if (!job_)
+ if (job_->WasCanceled())
return;
if (!context_) {
@@ -391,7 +543,7 @@ void ServiceWorkerControlleeRequestHandler::OnUpdatedVersionStatusChanged(
const scoped_refptr<ServiceWorkerRegistration>& registration,
const scoped_refptr<ServiceWorkerVersion>& version) {
// The job may have been canceled and then destroyed before this was invoked.
- if (!job_)
+ if (job_->WasCanceled())
return;
if (!context_) {

Powered by Google App Engine
This is Rietveld 408576698