service_worker_write_to_cache_job.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/service_worker/service_worker_disk_cache.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/service_worker/service_worker_metrics.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/io_buffer.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/net_errors.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_request_headers.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_response_headers.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_util.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_context.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/url_request/url_request_status.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob(
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::NetworkDelegate* network_delegate,
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ResourceType::Type resource_type,
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::WeakPtr<ServiceWorkerContextCore> context,
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ServiceWorkerVersion* version,
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int64 response_id)
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : net::URLRequestJob(request, network_delegate),
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      resource_type_(resource_type),
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      context_(context),
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_(request->url()),
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      response_id_(response_id),
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      version_(version),
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      has_been_killed_(false),
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      did_notify_started_(false),
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      did_notify_finished_(false),
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      weak_factory_(this) {
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitNetRequest();
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ServiceWorkerWriteToCacheJob::~ServiceWorkerWriteToCacheJob() {
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(did_notify_started_, did_notify_finished_);
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::Start() {
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NotifyStartError(net::URLRequestStatus(
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version_->script_cache_map()->NotifyStartedCaching(
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_, response_id_);
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  did_notify_started_ = true;
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StartNetRequest();
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::Kill() {
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (has_been_killed_)
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  has_been_killed_ = true;
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_.reset();
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (did_notify_started_ && !did_notify_finished_) {
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    version_->script_cache_map()->NotifyFinishedCaching(
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        url_, false);
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    did_notify_finished_ = true;
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_.reset();
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  context_.reset();
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::URLRequestJob::Kill();
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)net::LoadState ServiceWorkerWriteToCacheJob::GetLoadState() const {
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (writer_ && writer_->IsWritePending())
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return net::LOAD_STATE_WAITING_FOR_APPCACHE;
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (net_request_)
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return net_request_->GetLoadState().state;
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return net::LOAD_STATE_IDLE;
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceWorkerWriteToCacheJob::GetCharset(std::string* charset) {
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info()->headers->GetCharset(charset);
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceWorkerWriteToCacheJob::GetMimeType(std::string* mime_type) const {
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info()->headers->GetMimeType(mime_type);
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::GetResponseInfo(
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::HttpResponseInfo* info) {
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *info = *http_info();
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ServiceWorkerWriteToCacheJob::GetResponseCode() const {
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!http_info())
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return -1;
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info()->headers->response_code();
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders(
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const net::HttpRequestHeaders& headers) {
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string value;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!headers.GetHeader(net::HttpRequestHeaders::kRange, &value));
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->SetExtraRequestHeaders(headers);
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ServiceWorkerWriteToCacheJob::ReadRawData(
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::IOBuffer* buf,
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int buf_size,
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int *bytes_read) {
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net::URLRequestStatus status = ReadNetData(buf, buf_size, bytes_read);
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(status);
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (status.is_io_pending())
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // No more data to process, the job is complete.
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_buffer_ = NULL;
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version_->script_cache_map()->NotifyFinishedCaching(
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_, status.is_success());
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  did_notify_finished_ = true;
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return status.is_success();
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const net::HttpResponseInfo* ServiceWorkerWriteToCacheJob::http_info() const {
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return http_info_.get();
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::InitNetRequest() {
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(request());
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_ = request()->context()->CreateRequest(
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request()->url(),
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request()->priority(),
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this,
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      this->GetCookieStore());
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->set_first_party_for_cookies(
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      request()->first_party_for_cookies());
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->SetReferrer(request()->referrer());
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (resource_type_ == ResourceType::SERVICE_WORKER) {
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // This will get copied into net_request_ when URLRequest::StartJob calls
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders.
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    request()->SetExtraRequestHeaderByName("Service-Worker", "script", true);
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::StartNetRequest() {
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  net_request_->Start();  // We'll continue in OnResponseStarted.
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)net::URLRequestStatus ServiceWorkerWriteToCacheJob::ReadNetData(
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::IOBuffer* buf,
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int buf_size,
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int *bytes_read) {
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_GT(buf_size, 0);
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(bytes_read);
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *bytes_read = 0;
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_buffer_ = buf;
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int net_bytes_read = 0;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!net_request_->Read(buf, buf_size, &net_bytes_read)) {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (net_request_->status().is_io_pending())
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return net_request_->status();
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(!net_request_->status().is_success());
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return net_request_->status();
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (net_bytes_read != 0) {
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WriteDataToCache(net_bytes_read);
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(GetStatus().is_io_pending());
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return GetStatus();
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(net_request_->status().is_success());
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return net_request_->status();
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::WriteHeadersToCache() {
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_ = context_->storage()->CreateResponseWriter(response_id_);
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  info_buffer_ = new HttpResponseInfoIOBuffer(
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new net::HttpResponseInfo(net_request_->response_info()));
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_->WriteInfo(
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      info_buffer_,
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete,
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnWriteHeadersComplete(int result) {
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus());  // Clear the IO_PENDING status
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (result < 0) {
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerMetrics::CountWriteResponseResult(
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ServiceWorkerMetrics::WRITE_HEADERS_ERROR);
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, result));
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  http_info_.reset(info_buffer_->http_info.release());
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  info_buffer_ = NULL;
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyHeadersComplete();
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::WriteDataToCache(int amount_to_write) {
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(0, amount_to_write);
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  writer_->WriteData(
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      io_buffer_, amount_to_write,
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&ServiceWorkerWriteToCacheJob::OnWriteDataComplete,
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnWriteDataComplete(int result) {
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(0, result);
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_buffer_ = NULL;
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context_) {
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (result < 0) {
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ServiceWorkerMetrics::CountWriteResponseResult(
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ServiceWorkerMetrics::WRITE_DATA_ERROR);
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, result));
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ServiceWorkerMetrics::CountWriteResponseResult(
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ServiceWorkerMetrics::WRITE_OK);
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(net::URLRequestStatus());  // Clear the IO_PENDING status
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyReadComplete(result);
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnReceivedRedirect(
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& new_url,
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool* defer_redirect) {
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Script resources can't redirect.
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnAuthRequired(
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::AuthChallengeInfo* auth_info) {
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(michaeln): Pass this thru to our jobs client.
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnCertificateRequested(
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::SSLCertRequestInfo* cert_request_info) {
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(michaeln): Pass this thru to our jobs client.
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // see NotifyCertificateRequested.
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob:: OnSSLCertificateError(
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const net::SSLInfo& ssl_info,
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool fatal) {
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(michaeln): Pass this thru to our jobs client,
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // see NotifySSLCertificateError.
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(net::URLRequestStatus(
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::URLRequestStatus::FAILED, net::ERR_FAILED));
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnBeforeNetworkStart(
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool* defer) {
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyBeforeNetworkStart(defer);
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnResponseStarted(
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request) {
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!request->status().is_success()) {
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(request->status());
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (request->GetResponseCode() / 100 != 2) {
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(net::URLRequestStatus(
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        net::URLRequestStatus::FAILED, net::ERR_FAILED));
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // TODO(michaeln): Instead of error'ing immediately, send the net
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // response to our consumer, just don't cache it?
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WriteHeadersToCache();
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::OnReadCompleted(
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::URLRequest* request,
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int bytes_read) {
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(net_request_, request);
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!request->status().is_success()) {
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    AsyncNotifyDoneHelper(request->status());
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (bytes_read > 0) {
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WriteDataToCache(bytes_read);
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We're done with all.
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AsyncNotifyDoneHelper(request->status());
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return;
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerWriteToCacheJob::AsyncNotifyDoneHelper(
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const net::URLRequestStatus& status) {
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!status.is_io_pending());
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  version_->script_cache_map()->NotifyFinishedCaching(
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url_, status.is_success());
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  did_notify_finished_ = true;
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetStatus(status);
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NotifyDone(status);
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace content
335