service_worker_controllee_request_handler.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved. 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file. 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_controllee_request_handler.h" 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_context_core.h" 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_provider_host.h" 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_registration.h" 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_url_request_job.h" 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_utils.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/common/service_worker/service_worker_types.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/base/net_util.h" 145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/url_request/url_request.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace content { 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::WeakPtr<ServiceWorkerContextCore> context, 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::WeakPtr<ServiceWorkerProviderHost> provider_host, 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context, 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ResourceType::Type resource_type) 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : ServiceWorkerRequestHandler(context, 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider_host, 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context, 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) resource_type), 275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_factory_(this) { 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerControlleeRequestHandler:: 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ~ServiceWorkerControlleeRequestHandler() { 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunet::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob( 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::URLRequest* request, 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::NetworkDelegate* network_delegate) { 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!context_ || !provider_host_) { 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We can't do anything other than to fall back to network. 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_ = NULL; 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NULL; 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // This may get called multiple times for original and redirect requests: 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // A. original request case: job_ is null, no previous location info. 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // B. redirect or restarted request case: 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // a) job_ is non-null if the previous location was forwarded to SW. 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // b) job_ is null if the previous location was fallback. 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // c) job_ is non-null if additional restart was required to fall back. 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We've come here by restart, we already have original request and it 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // tells we should fallback to network. (Case B-c) 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (job_.get() && job_->ShouldFallbackToNetwork()) { 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_ = NULL; 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NULL; 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // It's for original request (A) or redirect case (B-a or B-b). 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker()); 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_ = new ServiceWorkerURLRequestJob( 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request, network_delegate, provider_host_, blob_storage_context_); 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (ServiceWorkerUtils::IsMainResourceType(resource_type_)) 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PrepareForMainResource(request->url()); 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu else 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PrepareForSubResource(); 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (job_->ShouldFallbackToNetwork()) { 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If we know we can fallback to network at this point (in case 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // the storage lookup returned immediately), just return NULL here to 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // fallback to network. 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_ = NULL; 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NULL; 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return job_.get(); 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerControlleeRequestHandler::PrepareForMainResource( 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL& url) { 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(job_.get()); 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(context_); 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The corresponding provider_host may already have associate version in 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // redirect case, unassociate it now. 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu provider_host_->SetActiveVersion(NULL); 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider_host_->SetWaitingVersion(NULL); 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GURL stripped_url = net::SimplifyUrlForRequest(url); 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_host_->SetDocumentUrl(stripped_url); 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu context_->storage()->FindRegistrationForDocument( 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) stripped_url, 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&self::DidLookupRegistrationForMainResource, 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_factory_.GetWeakPtr())); 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource( 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWorkerStatusCode status, 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const scoped_refptr<ServiceWorkerRegistration>& registration) { 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(job_.get()); 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (status != SERVICE_WORKER_OK || !registration->active_version()) { 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // No registration, or no active version for the registration is available. 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_->FallbackToNetwork(); 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(michaeln): should SetWaitingVersion() even if no active version so 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // so the versions in the pipeline (.installing, .waiting) show up in the 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // attribute values. 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(registration); 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu provider_host_->SetActiveVersion(registration->active_version()); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider_host_->SetWaitingVersion(registration->waiting_version()); 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_->ForwardToServiceWorker(); 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerControlleeRequestHandler::PrepareForSubResource() { 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(job_.get()); 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(context_); 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(provider_host_->active_version()); 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_->ForwardToServiceWorker(); 1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace content 122