File: service_worker_context_request_handler.cc

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (129 lines) | stat: -rw-r--r-- 5,294 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/service_worker/service_worker_context_request_handler.h"

#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_read_from_cache_job.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
#include "content/public/browser/resource_context.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request.h"

namespace content {

ServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler(
    base::WeakPtr<ServiceWorkerContextCore> context,
    base::WeakPtr<ServiceWorkerProviderHost> provider_host,
    base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
    ResourceType resource_type)
    : ServiceWorkerRequestHandler(context,
                                  provider_host,
                                  blob_storage_context,
                                  resource_type),
      version_(provider_host_->running_hosted_version()) {
  DCHECK(provider_host_->IsHostToRunningServiceWorker());
}

ServiceWorkerContextRequestHandler::~ServiceWorkerContextRequestHandler() {
}

net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
    net::URLRequest* request,
    net::NetworkDelegate* network_delegate,
    ResourceContext* resource_context) {
  if (!provider_host_ || !version_.get() || !context_)
    return NULL;

  // We currently have no use case for hijacking a redirected request.
  if (request->url_chain().size() > 1)
    return NULL;

  // We only use the script cache for main script loading and
  // importScripts(), even if a cached script is xhr'd, we don't
  // retrieve it from the script cache.
  // TODO(michaeln): Get the desired behavior clarified in the spec,
  // and make tweak the behavior here to match.
  if (resource_type_ != RESOURCE_TYPE_SERVICE_WORKER &&
      resource_type_ != RESOURCE_TYPE_SCRIPT) {
    return NULL;
  }

  if (ShouldAddToScriptCache(request->url())) {
    ServiceWorkerRegistration* registration =
        context_->GetLiveRegistration(version_->registration_id());
    DCHECK(registration);  // We're registering or updating so must be there.

    int64 response_id = context_->storage()->NewResourceId();
    if (response_id == kInvalidServiceWorkerResponseId)
      return NULL;

    // Bypass the browser cache for initial installs and update
    // checks after 24 hours have passed.
    int extra_load_flags = 0;
    base::TimeDelta time_since_last_check =
        base::Time::Now() - registration->last_update_check();
    if (time_since_last_check > base::TimeDelta::FromHours(24))
      extra_load_flags = net::LOAD_BYPASS_CACHE;

    return new ServiceWorkerWriteToCacheJob(request,
                                            network_delegate,
                                            resource_type_,
                                            context_,
                                            version_.get(),
                                            extra_load_flags,
                                            response_id);
  }

  int64 response_id = kInvalidServiceWorkerResponseId;
  if (ShouldReadFromScriptCache(request->url(), &response_id)) {
    return new ServiceWorkerReadFromCacheJob(
        request, network_delegate, context_, response_id);
  }

  // NULL means use the network.
  return NULL;
}

void ServiceWorkerContextRequestHandler::GetExtraResponseInfo(
    bool* was_fetched_via_service_worker,
    bool* was_fallback_required_by_service_worker,
    GURL* original_url_via_service_worker,
    blink::WebServiceWorkerResponseType* response_type_via_service_worker,
    base::TimeTicks* fetch_start_time,
    base::TimeTicks* fetch_ready_time,
    base::TimeTicks* fetch_end_time) const {
  *was_fetched_via_service_worker = false;
  *was_fallback_required_by_service_worker = false;
  *original_url_via_service_worker = GURL();
  *response_type_via_service_worker =
      blink::WebServiceWorkerResponseTypeDefault;
}

bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
    const GURL& url) {
  // We only write imports that occur during the initial eval.
  if (version_->status() != ServiceWorkerVersion::NEW &&
      version_->status() != ServiceWorkerVersion::INSTALLING) {
    return false;
  }
  return version_->script_cache_map()->LookupResourceId(url) ==
         kInvalidServiceWorkerResponseId;
}

bool ServiceWorkerContextRequestHandler::ShouldReadFromScriptCache(
    const GURL& url, int64* response_id_out) {
  // We don't read from the script cache until the version is INSTALLED.
  if (version_->status() == ServiceWorkerVersion::NEW ||
      version_->status() == ServiceWorkerVersion::INSTALLING)
    return false;
  *response_id_out = version_->script_cache_map()->LookupResourceId(url);
  return *response_id_out != kInvalidServiceWorkerResponseId;
}

}  // namespace content