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.
5 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
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"
17 ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
18 base::WeakPtr
<ServiceWorkerContextCore
> context
,
19 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
,
20 ResourceType::Type resource_type
)
21 : ServiceWorkerRequestHandler(context
, provider_host
, resource_type
),
25 ServiceWorkerControlleeRequestHandler::
26 ~ServiceWorkerControlleeRequestHandler() {
29 net::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.
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.
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()) {
52 // It's for original request (A) or redirect case (B-a or B-b).
53 DCHECK(!job_
.get() || job_
->ShouldForwardToServiceWorker());
55 job_
= new ServiceWorkerURLRequestJob(request
, network_delegate
,
57 if (ServiceWorkerUtils::IsMainResourceType(resource_type_
))
58 PrepareForMainResource(request
->url());
60 PrepareForSubResource();
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.
73 void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
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(
84 base::Bind(&self::DidLookupRegistrationForMainResource
,
85 weak_factory_
.GetWeakPtr()));
89 ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
90 ServiceWorkerStatusCode status
,
91 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
93 if (status
!= SERVICE_WORKER_OK
|| !registration
->active_version()) {
94 // No registration, or no active version for the registration is available.
95 job_
->FallbackToNetwork();
98 // TODO(michaeln): should SetPendingVersion() even if no active version so
99 // so the versions in the pipeline (.installing, .waiting) show up in the
101 DCHECK(registration
);
102 provider_host_
->SetActiveVersion(registration
->active_version());
103 provider_host_
->SetPendingVersion(registration
->pending_version());
104 job_
->ForwardToServiceWorker();
107 void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() {
110 DCHECK(provider_host_
->active_version());
111 job_
->ForwardToServiceWorker();
114 } // namespace content