service_worker_controllee_request_handler.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com// Copyright 2014 The Chromium Authors. All rights reserved. 2c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com// Use of this source code is governed by a BSD-style license that can be 3c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com// found in the LICENSE file. 4c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 5c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/browser/service_worker/service_worker_controllee_request_handler.h" 6c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 7c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/browser/service_worker/service_worker_context_core.h" 8c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/browser/service_worker/service_worker_provider_host.h" 9c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/browser/service_worker/service_worker_registration.h" 10c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/browser/service_worker/service_worker_url_request_job.h" 11c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/browser/service_worker/service_worker_utils.h" 12c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "content/common/service_worker/service_worker_types.h" 13c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com#include "net/url_request/url_request.h" 14c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 15c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comnamespace content { 16c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 17c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( 18c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com base::WeakPtr<ServiceWorkerContextCore> context, 19c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com base::WeakPtr<ServiceWorkerProviderHost> provider_host, 20c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context, 21c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com ResourceType::Type resource_type) 22c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com : ServiceWorkerRequestHandler(context, 23c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com provider_host, 24c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com blob_storage_context, 25c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com resource_type), 26c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com weak_factory_(this) { 27c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} 28c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 29c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comServiceWorkerControlleeRequestHandler:: 30c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com ~ServiceWorkerControlleeRequestHandler() { 31c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} 32c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 33c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comnet::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob( 34c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com net::URLRequest* request, 35c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com net::NetworkDelegate* network_delegate) { 36c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com if (!context_ || !provider_host_) { 37c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // We can't do anything other than to fall back to network. 38c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_ = NULL; 39c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com return NULL; 40c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com } 41c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 42c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // This may get called multiple times for original and redirect requests: 43c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // A. original request case: job_ is null, no previous location info. 44c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // B. redirect or restarted request case: 45c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // a) job_ is non-null if the previous location was forwarded to SW. 46c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // b) job_ is null if the previous location was fallback. 47c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // c) job_ is non-null if additional restart was required to fall back. 48c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 49c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // We've come here by restart, we already have original request and it 50c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // tells we should fallback to network. (Case B-c) 51c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com if (job_.get() && job_->ShouldFallbackToNetwork()) { 52c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_ = NULL; 53c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com return NULL; 54c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com } 55c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 56c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // It's for original request (A) or redirect case (B-a or B-b). 57c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker()); 58c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 59c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_ = new ServiceWorkerURLRequestJob( 60c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com request, network_delegate, provider_host_, blob_storage_context_); 61c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com if (ServiceWorkerUtils::IsMainResourceType(resource_type_)) 62c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com PrepareForMainResource(request->url()); 63c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com else 64c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com PrepareForSubResource(); 65c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 66c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com if (job_->ShouldFallbackToNetwork()) { 67c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // If we know we can fallback to network at this point (in case 68c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // the storage lookup returned immediately), just return NULL here to 69c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // fallback to network. 70c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_ = NULL; 71c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com return NULL; 72c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com } 73c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 74c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com return job_.get(); 75c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} 76c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 77c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comvoid ServiceWorkerControlleeRequestHandler::PrepareForMainResource( 78c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com const GURL& url) { 79c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(job_.get()); 80c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(context_); 81c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // The corresponding provider_host may already have associate version in 82c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // redirect case, unassociate it now. 83c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com provider_host_->SetActiveVersion(NULL); 84c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com provider_host_->SetWaitingVersion(NULL); 85c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com provider_host_->set_document_url(url); 86c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com context_->storage()->FindRegistrationForDocument( 87c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com url, 88c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com base::Bind(&self::DidLookupRegistrationForMainResource, 89c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com weak_factory_.GetWeakPtr())); 90c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} 91c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 92c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comvoid 93c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource( 94c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com ServiceWorkerStatusCode status, 95c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com const scoped_refptr<ServiceWorkerRegistration>& registration) { 96c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(job_.get()); 97c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com if (status != SERVICE_WORKER_OK || !registration->active_version()) { 98c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // No registration, or no active version for the registration is available. 99c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_->FallbackToNetwork(); 100c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com return; 101c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com } 102c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // TODO(michaeln): should SetWaitingVersion() even if no active version so 103c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // so the versions in the pipeline (.installing, .waiting) show up in the 104c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com // attribute values. 105c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(registration); 106c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com provider_host_->SetActiveVersion(registration->active_version()); 107c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com provider_host_->SetWaitingVersion(registration->waiting_version()); 108c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_->ForwardToServiceWorker(); 109c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} 110c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 111c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.comvoid ServiceWorkerControlleeRequestHandler::PrepareForSubResource() { 112c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(job_.get()); 113c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(context_); 114c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com DCHECK(provider_host_->active_version()); 115c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com job_->ForwardToServiceWorker(); 116c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} 117c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com 118c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com} // namespace content 119c682590538a27d73489bc91c098e000fdfb07ccfcaryclark@google.com