1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_disk_cache.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/service_worker/service_worker_metrics.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/io_buffer.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/net_errors.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_request_headers.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_response_headers.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_util.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_context.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_status.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content {
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob(
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::NetworkDelegate* network_delegate,
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ResourceType resource_type,
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::WeakPtr<ServiceWorkerContextCore> context,
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerVersion* version,
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int extra_load_flags,
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int64 response_id)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : net::URLRequestJob(request, network_delegate),
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      resource_type_(resource_type),
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      context_(context),
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_(request->url()),
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      response_id_(response_id),
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      version_(version),
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      has_been_killed_(false),
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      did_notify_started_(false),
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      did_notify_finished_(false),
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      weak_factory_(this) {
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  InitNetRequest(extra_load_flags);
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerWriteToCacheJob::~ServiceWorkerWriteToCacheJob() {
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(did_notify_started_, did_notify_finished_);
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::Start() {
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker",
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "ServiceWorkerWriteToCacheJob::ExecutingJob",
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           this,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           "URL", request_->url().spec());
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NotifyStartError(net::URLRequestStatus(
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version_->script_cache_map()->NotifyStartedCaching(
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_, response_id_);
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  did_notify_started_ = true;
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StartNetRequest();
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::Kill() {
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (has_been_killed_)
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  has_been_killed_ = true;
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_.reset();
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (did_notify_started_ && !did_notify_finished_) {
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version_->script_cache_map()->NotifyFinishedCaching(
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url_,
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_ABORTED));
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    did_notify_finished_ = true;
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_.reset();
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  context_.reset();
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::URLRequestJob::Kill();
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)net::LoadState ServiceWorkerWriteToCacheJob::GetLoadState() const {
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (writer_ && writer_->IsWritePending())
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return net::LOAD_STATE_WAITING_FOR_APPCACHE;
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (net_request_)
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return net_request_->GetLoadState().state;
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return net::LOAD_STATE_IDLE;
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceWorkerWriteToCacheJob::GetCharset(std::string* charset) {
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info()->headers->GetCharset(charset);
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceWorkerWriteToCacheJob::GetMimeType(std::string* mime_type) const {
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info()->headers->GetMimeType(mime_type);
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::GetResponseInfo(
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::HttpResponseInfo* info) {
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *info = *http_info();
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ServiceWorkerWriteToCacheJob::GetResponseCode() const {
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return -1;
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info()->headers->response_code();
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders(
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const net::HttpRequestHeaders& headers) {
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string value;
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!headers.GetHeader(net::HttpRequestHeaders::kRange, &value));
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->SetExtraRequestHeaders(headers);
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceWorkerWriteToCacheJob::ReadRawData(
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::IOBuffer* buf,
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int buf_size,
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int *bytes_read) {
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::URLRequestStatus status = ReadNetData(buf, buf_size, bytes_read);
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(status);
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status.is_io_pending())
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // No more data to process, the job is complete.
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_buffer_ = NULL;
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version_->script_cache_map()->NotifyFinishedCaching(
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url_, net::URLRequestStatus());
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  did_notify_finished_ = true;
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return status.is_success();
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const net::HttpResponseInfo* ServiceWorkerWriteToCacheJob::http_info() const {
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info_.get();
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::InitNetRequest(
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int extra_load_flags) {
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(request());
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_ = request()->context()->CreateRequest(
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request()->url(),
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request()->priority(),
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this,
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this->GetCookieStore());
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->set_first_party_for_cookies(
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request()->first_party_for_cookies());
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->SetReferrer(request()->referrer());
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (extra_load_flags)
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    net_request_->SetLoadFlags(net_request_->load_flags() | extra_load_flags);
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER) {
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // This will get copied into net_request_ when URLRequest::StartJob calls
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders.
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    request()->SetExtraRequestHeaderByName("Service-Worker", "script", true);
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::StartNetRequest() {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerWriteToCacheJob::ExecutingJob",
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               this,
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "NetRequest");
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->Start();  // We'll continue in OnResponseStarted.
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)net::URLRequestStatus ServiceWorkerWriteToCacheJob::ReadNetData(
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::IOBuffer* buf,
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int buf_size,
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int *bytes_read) {
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GT(buf_size, 0);
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(bytes_read);
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *bytes_read = 0;
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_buffer_ = buf;
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int net_bytes_read = 0;
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!net_request_->Read(buf, buf_size, &net_bytes_read)) {
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (net_request_->status().is_io_pending())
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return net_request_->status();
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(!net_request_->status().is_success());
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return net_request_->status();
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (net_bytes_read != 0) {
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WriteDataToCache(net_bytes_read);
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(GetStatus().is_io_pending());
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return GetStatus();
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(net_request_->status().is_success());
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return net_request_->status();
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::WriteHeadersToCache() {
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerWriteToCacheJob::ExecutingJob",
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               this,
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "WriteHeadersToCache");
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_ = context_->storage()->CreateResponseWriter(response_id_);
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  info_buffer_ = new HttpResponseInfoIOBuffer(
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new net::HttpResponseInfo(net_request_->response_info()));
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_->WriteInfo(
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      info_buffer_.get(),
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete(int result) {
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus());  // Clear the IO_PENDING status
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (result < 0) {
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerMetrics::CountWriteResponseResult(
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ServiceWorkerMetrics::WRITE_HEADERS_ERROR);
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, result));
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  http_info_.reset(info_buffer_->http_info.release());
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  info_buffer_ = NULL;
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerWriteToCacheJob::ExecutingJob",
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               this,
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "WriteHeadersToCacheCompleted");
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyHeadersComplete();
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::WriteDataToCache(int amount_to_write) {
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(0, amount_to_write);
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO1("ServiceWorker",
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerWriteToCacheJob::ExecutingJob",
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               this,
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "WriteDataToCache",
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "Amount to write", amount_to_write);
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_->WriteData(
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      io_buffer_.get(),
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      amount_to_write,
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnWriteDataComplete(int result) {
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(0, result);
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_buffer_ = NULL;
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (result < 0) {
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerMetrics::CountWriteResponseResult(
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ServiceWorkerMetrics::WRITE_DATA_ERROR);
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, result));
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceWorkerMetrics::CountWriteResponseResult(
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ServiceWorkerMetrics::WRITE_OK);
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus());  // Clear the IO_PENDING status
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyReadComplete(result);
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_END0("ServiceWorker",
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         "ServiceWorkerWriteToCacheJob::ExecutingJob",
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         this);
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnReceivedRedirect(
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
2766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const net::RedirectInfo& redirect_info,
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool* defer_redirect) {
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerWriteToCacheJob::OnReceivedRedirect");
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Script resources can't redirect.
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      net::URLRequestStatus::FAILED, net::ERR_UNSAFE_REDIRECT));
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnAuthRequired(
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::AuthChallengeInfo* auth_info) {
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerWriteToCacheJob::OnAuthRequired");
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(michaeln): Pass this thru to our jobs client.
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnCertificateRequested(
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::SSLCertRequestInfo* cert_request_info) {
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerWriteToCacheJob::OnCertificateRequested");
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(michaeln): Pass this thru to our jobs client.
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // see NotifyCertificateRequested.
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob:: OnSSLCertificateError(
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const net::SSLInfo& ssl_info,
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool fatal) {
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerWriteToCacheJob::OnSSLCertificateError");
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(michaeln): Pass this thru to our jobs client,
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // see NotifySSLCertificateError.
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart(
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool* defer) {
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("ServiceWorker",
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart");
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyBeforeNetworkStart(defer);
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnResponseStarted(
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request) {
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!request->status().is_success()) {
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(request->status());
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (request->GetResponseCode() / 100 != 2) {
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // TODO(michaeln): Instead of error'ing immediately, send the net
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // response to our consumer, just don't cache it?
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // To prevent most user-uploaded content from being used as a serviceworker.
3466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (version_->script_url() == url_) {
3476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    std::string mime_type;
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    request->GetMimeType(&mime_type);
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (mime_type != "application/x-javascript" &&
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        mime_type != "text/javascript" &&
3516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        mime_type != "application/javascript") {
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      AsyncNotifyDoneHelper(net::URLRequestStatus(
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          net::URLRequestStatus::FAILED, net::ERR_INSECURE_RESPONSE));
3546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return;
3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
3566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WriteHeadersToCache();
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnReadCompleted(
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int bytes_read) {
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!request->status().is_success()) {
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(request->status());
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (bytes_read > 0) {
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WriteDataToCache(bytes_read);
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO0("ServiceWorker",
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "ServiceWorkerWriteToCacheJob::ExecutingJob",
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               this,
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "WriteHeadersToCache");
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We're done with all.
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(request->status());
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return;
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::AsyncNotifyDoneHelper(
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const net::URLRequestStatus& status) {
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!status.is_io_pending());
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  version_->script_cache_map()->NotifyFinishedCaching(url_, status);
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  did_notify_finished_ = true;
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(status);
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyDone(status);
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace content
391