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