service_worker_context_request_handler.cc revision 116680a4aac90f2aa7413d9095a592090648e557
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_context_request_handler.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/service_worker/service_worker_provider_host.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/service_worker/service_worker_read_from_cache_job.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_storage.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/service_worker/service_worker_version.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/url_request/url_request.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace content {
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler(
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::WeakPtr<ServiceWorkerContextCore> context,
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::WeakPtr<ServiceWorkerProviderHost> provider_host,
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context,
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ResourceType::Type resource_type)
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : ServiceWorkerRequestHandler(context,
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  provider_host,
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  blob_storage_context,
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  resource_type),
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      version_(provider_host_->running_hosted_version()) {
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(provider_host_->IsHostToRunningServiceWorker());
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceWorkerContextRequestHandler::~ServiceWorkerContextRequestHandler() {
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunet::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    net::URLRequest* request,
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    net::NetworkDelegate* network_delegate) {
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!provider_host_ || !version_ || !context_)
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We currently have no use case for hijacking a redirected request.
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (request->url_chain().size() > 1)
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return NULL;
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // We only use the script cache for main script loading and
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // importScripts(), even if a cached script is xhr'd, we don't
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // retrieve it from the script cache.
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // TODO(michaeln): Get the desired behavior clarified in the spec,
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // and make tweak the behavior here to match.
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (resource_type_ != ResourceType::SERVICE_WORKER &&
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      resource_type_ != ResourceType::SCRIPT) {
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return NULL;
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (ShouldAddToScriptCache(request->url())) {
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int64 response_id = context_->storage()->NewResourceId();
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (response_id == kInvalidServiceWorkerResponseId)
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return NULL;
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return new ServiceWorkerWriteToCacheJob(request,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            network_delegate,
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            resource_type_,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            context_,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            version_,
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            response_id);
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int64 response_id = kInvalidServiceWorkerResponseId;
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (ShouldReadFromScriptCache(request->url(), &response_id)) {
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return new ServiceWorkerReadFromCacheJob(
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        request, network_delegate, context_, response_id);
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // NULL means use the network.
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return NULL;
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ServiceWorkerContextRequestHandler::ShouldAddToScriptCache(
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GURL& url) {
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We only write imports that occur during the initial eval.
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (version_->status() != ServiceWorkerVersion::NEW &&
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      version_->status() != ServiceWorkerVersion::INSTALLING) {
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return version_->script_cache_map()->Lookup(url) ==
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            kInvalidServiceWorkerResponseId;
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool ServiceWorkerContextRequestHandler::ShouldReadFromScriptCache(
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GURL& url, int64* response_id_out) {
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // We don't read from the script cache until the version is INSTALLED.
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (version_->status() == ServiceWorkerVersion::NEW ||
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      version_->status() == ServiceWorkerVersion::INSTALLING)
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *response_id_out = version_->script_cache_map()->Lookup(url);
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return *response_id_out != kInvalidServiceWorkerResponseId;
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace content
97