Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_controllee_request_handler.cc
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.
4
5 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
6
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"
14
15 namespace content {
16
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),
22       weak_factory_(this) {
23 }
24
25 ServiceWorkerControlleeRequestHandler::
26     ~ServiceWorkerControlleeRequestHandler() {
27 }
28
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.
34     job_ = NULL;
35     return NULL;
36   }
37
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.
44
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()) {
48     job_ = NULL;
49     return NULL;
50   }
51
52   // It's for original request (A) or redirect case (B-a or B-b).
53   DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker());
54
55   job_ = new ServiceWorkerURLRequestJob(request, network_delegate,
56                                         provider_host_);
57   if (ServiceWorkerUtils::IsMainResourceType(resource_type_))
58     PrepareForMainResource(request->url());
59   else
60     PrepareForSubResource();
61
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.
66     job_ = NULL;
67     return NULL;
68   }
69
70   return job_.get();
71 }
72
73 void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
74     const GURL& url) {
75   DCHECK(job_.get());
76   DCHECK(context_);
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(
83       url,
84       base::Bind(&self::DidLookupRegistrationForMainResource,
85                  weak_factory_.GetWeakPtr()));
86 }
87
88 void
89 ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
90     ServiceWorkerStatusCode status,
91     const scoped_refptr<ServiceWorkerRegistration>& registration) {
92   DCHECK(job_.get());
93   if (status != SERVICE_WORKER_OK || !registration->active_version()) {
94     // No registration, or no active version for the registration is available.
95     job_->FallbackToNetwork();
96     return;
97   }
98   // TODO(michaeln): should SetPendingVersion() even if no active version so
99   // so the versions in the pipeline (.installing, .waiting) show up in the
100   // attribute values.
101   DCHECK(registration);
102   provider_host_->SetActiveVersion(registration->active_version());
103   provider_host_->SetPendingVersion(registration->pending_version());
104   job_->ForwardToServiceWorker();
105 }
106
107 void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() {
108   DCHECK(job_.get());
109   DCHECK(context_);
110   DCHECK(provider_host_->active_version());
111   job_->ForwardToServiceWorker();
112 }
113
114 }  // namespace content