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