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