service_worker_controllee_request_handler.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/service_worker/service_worker_metrics.h" 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_provider_host.h" 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_registration.h" 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_url_request_job.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_utils.h" 135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/common/service_worker/service_worker_types.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/base/load_flags.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/base/net_util.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/url_request/url_request.h" 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace content { 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler( 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::WeakPtr<ServiceWorkerContextCore> context, 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::WeakPtr<ServiceWorkerProviderHost> provider_host, 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context, 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType resource_type) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : ServiceWorkerRequestHandler(context, 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) provider_host, 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context, 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) resource_type), 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch is_main_resource_load_( 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ServiceWorkerUtils::IsMainResourceType(resource_type)), 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_factory_(this) { 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerControlleeRequestHandler:: 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ~ServiceWorkerControlleeRequestHandler() { 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Navigation triggers an update to occur shortly after the page and 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // its initial subresources load. 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (provider_host_ && provider_host_->active_version()) { 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_main_resource_load_) 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch provider_host_->active_version()->ScheduleUpdate(); 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch provider_host_->active_version()->DeferScheduledUpdate(); 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunet::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob( 475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::URLRequest* request, 485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::NetworkDelegate* network_delegate) { 495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!context_ || !provider_host_) { 505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We can't do anything other than to fall back to network. 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_ = NULL; 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NULL; 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (request->load_flags() & net::LOAD_BYPASS_CACHE) { 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_main_resource_load_) { 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch provider_host_->SetDocumentUrl( 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::SimplifyUrlForRequest(request->url())); 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch job_ = NULL; 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // This may get called multiple times for original and redirect requests: 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // A. original request case: job_ is null, no previous location info. 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // B. redirect or restarted request case: 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // a) job_ is non-null if the previous location was forwarded to SW. 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // b) job_ is null if the previous location was fallback. 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // c) job_ is non-null if additional restart was required to fall back. 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We've come here by restart, we already have original request and it 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // tells we should fallback to network. (Case B-c) 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (job_.get() && job_->ShouldFallbackToNetwork()) { 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_ = NULL; 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NULL; 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // It's for original request (A) or redirect case (B-a or B-b). 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker()); 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) job_ = new ServiceWorkerURLRequestJob( 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) request, network_delegate, provider_host_, blob_storage_context_); 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (is_main_resource_load_) 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PrepareForMainResource(request->url()); 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu else 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PrepareForSubResource(); 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (job_->ShouldFallbackToNetwork()) { 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If we know we can fallback to network at this point (in case 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // the storage lookup returned immediately), just return NULL here to 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // fallback to network. 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_ = NULL; 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return NULL; 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return job_.get(); 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerControlleeRequestHandler::GetExtraResponseInfo( 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool* was_fetched_via_service_worker, 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL* original_url_via_service_worker) const { 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!job_) { 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *was_fetched_via_service_worker = false; 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *original_url_via_service_worker = GURL(); 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) job_->GetExtraResponseInfo(was_fetched_via_service_worker, 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) original_url_via_service_worker); 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerControlleeRequestHandler::PrepareForMainResource( 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL& url) { 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(job_.get()); 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(context_); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The corresponding provider_host may already have associated a registration 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // in redirect case, unassociate it now. 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) provider_host_->UnassociateRegistration(); 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GURL stripped_url = net::SimplifyUrlForRequest(url); 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_host_->SetDocumentUrl(stripped_url); 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu context_->storage()->FindRegistrationForDocument( 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) stripped_url, 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&self::DidLookupRegistrationForMainResource, 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_factory_.GetWeakPtr())); 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource( 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWorkerStatusCode status, 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const scoped_refptr<ServiceWorkerRegistration>& registration) { 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(job_.get()); 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != SERVICE_WORKER_OK) { 1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_->FallbackToNetwork(); 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(registration); 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ServiceWorkerMetrics::CountControlledPageLoad(); 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Initiate activation of a waiting version. 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Usually a register job initiates activation but that 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // doesn't happen if the browser exits prior to activation 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // having occurred. This check handles that case. 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (registration->waiting_version()) 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration->ActivateWaitingVersionWhenReady(); 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<ServiceWorkerVersion> active_version = 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration->active_version(); 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Wait until it's activated before firing fetch events. 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (active_version && 1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) active_version->status() == ServiceWorkerVersion::ACTIVATING) { 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration->active_version()->RegisterStatusChangeCallback( 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&self::OnVersionStatusChanged, 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_factory_.GetWeakPtr(), 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration, 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) active_version)); 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!active_version || 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) active_version->status() != ServiceWorkerVersion::ACTIVATED) { 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) job_->FallbackToNetwork(); 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) provider_host_->AssociateRegistration(registration); 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) job_->ForwardToServiceWorker(); 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged( 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerRegistration* registration, 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerVersion* version) { 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (version != registration->active_version() || 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version->status() != ServiceWorkerVersion::ACTIVATED) { 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) job_->FallbackToNetwork(); 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) provider_host_->AssociateRegistration(registration); 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_->ForwardToServiceWorker(); 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceWorkerControlleeRequestHandler::PrepareForSubResource() { 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(job_.get()); 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(context_); 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(provider_host_->active_version()); 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu job_->ForwardToServiceWorker(); 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace content 192