Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_context_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_context_request_handler.h"
6
7 #include "base/time/time.h"
8 #include "content/browser/service_worker/service_worker_context_core.h"
9 #include "content/browser/service_worker/service_worker_provider_host.h"
10 #include "content/browser/service_worker/service_worker_read_from_cache_job.h"
11 #include "content/browser/service_worker/service_worker_storage.h"
12 #include "content/browser/service_worker/service_worker_version.h"
13 #include "content/browser/service_worker/service_worker_write_to_cache_job.h"
14 #include "net/base/load_flags.h"
15 #include "net/url_request/url_request.h"
16
17 namespace content {
18
19 ServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler(
20     base::WeakPtr<ServiceWorkerContextCore> context,
21     base::WeakPtr<ServiceWorkerProviderHost> provider_host,
22     base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
23     ResourceType resource_type)
24     : ServiceWorkerRequestHandler(context,
25                                   provider_host,
26                                   blob_storage_context,
27                                   resource_type),
28       version_(provider_host_->running_hosted_version()) {
29   DCHECK(provider_host_->IsHostToRunningServiceWorker());
30 }
31
32 ServiceWorkerContextRequestHandler::~ServiceWorkerContextRequestHandler() {
33 }
34
35 net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
36     net::URLRequest* request,
37     net::NetworkDelegate* network_delegate) {
38   if (!provider_host_ || !version_.get() || !context_)
39     return NULL;
40
41   // We currently have no use case for hijacking a redirected request.
42   if (request->url_chain().size() > 1)
43     return NULL;
44
45   // We only use the script cache for main script loading and
46   // importScripts(), even if a cached script is xhr'd, we don't
47   // retrieve it from the script cache.
48   // TODO(michaeln): Get the desired behavior clarified in the spec,
49   // and make tweak the behavior here to match.
50   if (resource_type_ != RESOURCE_TYPE_SERVICE_WORKER &&
51       resource_type_ != RESOURCE_TYPE_SCRIPT) {
52     return NULL;
53   }
54
55   if (ShouldAddToScriptCache(request->url())) {
56     ServiceWorkerRegistration* registration =
57         context_->GetLiveRegistration(version_->registration_id());
58     DCHECK(registration);  // We're registering or updating so must be there.
59
60     int64 response_id = context_->storage()->NewResourceId();
61     if (response_id == kInvalidServiceWorkerResponseId)
62       return NULL;
63
64     // Bypass the browser cache for initial installs and update
65     // checks after 24 hours have passed.
66     int extra_load_flags = 0;
67     base::TimeDelta time_since_last_check =
68         base::Time::Now() - registration->last_update_check();
69     if (time_since_last_check > base::TimeDelta::FromHours(24))
70       extra_load_flags = net::LOAD_BYPASS_CACHE;
71
72     return new ServiceWorkerWriteToCacheJob(request,
73                                             network_delegate,
74                                             resource_type_,
75                                             context_,
76                                             version_.get(),
77                                             extra_load_flags,
78                                             response_id);
79   }
80
81   int64 response_id = kInvalidServiceWorkerResponseId;
82   if (ShouldReadFromScriptCache(request->url(), &response_id)) {
83     return new ServiceWorkerReadFromCacheJob(
84         request, network_delegate, context_, response_id);
85   }
86
87   // NULL means use the network.
88   return NULL;
89 }
90
91 void ServiceWorkerContextRequestHandler::GetExtraResponseInfo(
92     bool* was_fetched_via_service_worker,
93     GURL* original_url_via_service_worker,
94     base::TimeTicks* fetch_start_time,
95     base::TimeTicks* fetch_ready_time,
96     base::TimeTicks* fetch_end_time) const {
97   *was_fetched_via_service_worker = false;
98   *original_url_via_service_worker = GURL();
99 }
100
101 bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
102     const GURL& url) {
103   // We only write imports that occur during the initial eval.
104   if (version_->status() != ServiceWorkerVersion::NEW &&
105       version_->status() != ServiceWorkerVersion::INSTALLING) {
106     return false;
107   }
108   return version_->script_cache_map()->Lookup(url) ==
109             kInvalidServiceWorkerResponseId;
110 }
111
112 bool ServiceWorkerContextRequestHandler::ShouldReadFromScriptCache(
113     const GURL& url, int64* response_id_out) {
114   // We don't read from the script cache until the version is INSTALLED.
115   if (version_->status() == ServiceWorkerVersion::NEW ||
116       version_->status() == ServiceWorkerVersion::INSTALLING)
117     return false;
118   *response_id_out = version_->script_cache_map()->Lookup(url);
119   return *response_id_out != kInvalidServiceWorkerResponseId;
120 }
121
122 }  // namespace content