service_worker_url_request_job.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_url_request_job.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/stringprintf.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_provider_host.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_request_headers.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_response_headers.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_response_info.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_util.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content {
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::URLRequest* request,
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::NetworkDelegate* network_delegate,
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::WeakPtr<ServiceWorkerProviderHost> provider_host)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : net::URLRequestJob(request, network_delegate),
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      provider_host_(provider_host),
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      response_type_(NOT_DETERMINED),
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      is_started_(false),
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      weak_factory_(this) {
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::FallbackToNetwork() {
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(NOT_DETERMINED, response_type_);
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  response_type_ = FALLBACK_TO_NETWORK;
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MaybeStartRequest();
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::ForwardToServiceWorker() {
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(NOT_DETERMINED, response_type_);
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  response_type_ = FORWARD_TO_SERVICE_WORKER;
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MaybeStartRequest();
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::Start() {
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  is_started_ = true;
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MaybeStartRequest();
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::Kill() {
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  net::URLRequestJob::Kill();
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fetch_dispatcher_.reset();
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const {
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(kinuko): refine this for better debug.
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return net::URLRequestJob::GetLoadState();
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) {
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!http_info())
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return http_info()->headers->GetCharset(charset);
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!http_info())
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return http_info()->headers->GetMimeType(mime_type);
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!http_info())
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  *info = *http_info();
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int ServiceWorkerURLRequestJob::GetResponseCode() const {
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!http_info())
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return -1;
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return http_info()->headers->response_code();
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::SetExtraRequestHeaders(
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const net::HttpRequestHeaders& headers) {
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string range_header;
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<net::HttpByteRange> ranges;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header) ||
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We don't support multiple range requests in one single URL request.
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (ranges.size() == 1U)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    byte_range_ = ranges[0];
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::ReadRawData(
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::IOBuffer* buf, int buf_size, int *bytes_read) {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(kinuko): Implement this.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If the response returned from ServiceWorker had an
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // identifier to on-disk data (e.g. blob or cache entry) we'll need to
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pull the body from disk.
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NOTIMPLEMENTED();
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  *bytes_read = 0;
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!http_response_info_)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return NULL;
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (range_response_info_)
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return range_response_info_.get();
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return http_response_info_.get();
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::MaybeStartRequest() {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (is_started_ && response_type_ != NOT_DETERMINED) {
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Start asynchronously.
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::MessageLoop::current()->PostTask(
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        FROM_HERE,
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ServiceWorkerURLRequestJob::StartRequest,
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::StartRequest() {
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (response_type_) {
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case NOT_DETERMINED:
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NOTREACHED();
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case FALLBACK_TO_NETWORK:
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Restart the request to create a new job. Our request handler will
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // return NULL, and the default job (which will hit network) should be
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // created.
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NotifyRestartRequired();
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case FORWARD_TO_SERVICE_WORKER:
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(provider_host_ && provider_host_->associated_version());
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(!fetch_dispatcher_);
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Send a fetch event to the ServiceWorker associated to the
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // provider_host.
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          request(), provider_host_->associated_version(),
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     weak_factory_.GetWeakPtr())));
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fetch_dispatcher_->Run();
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NOTREACHED();
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ServiceWorkerStatusCode status,
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ServiceWorkerFetchEventResult fetch_result,
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ServiceWorkerResponse& response) {
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fetch_dispatcher_.reset();
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Check if we're not orphaned.
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!request())
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status != SERVICE_WORKER_OK) {
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Dispatching event has been failed, falling back to the network.
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // (Tentative behavior described on github)
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(kinuko): consider returning error if we've come here because
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // unexpected worker termination etc (so that we could fix bugs).
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(kinuko): Would be nice to log the error case.
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    response_type_ = FALLBACK_TO_NETWORK;
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NotifyRestartRequired();
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Change the response type and restart the request to fallback to
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // the network.
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    response_type_ = FALLBACK_TO_NETWORK;
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NotifyRestartRequired();
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // We should have response now.
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result);
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CreateResponseHeader(response);
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NotifyHeadersComplete();
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::CreateResponseHeader(
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const ServiceWorkerResponse& response) {
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(kinuko): If the response has an identifier to on-disk cache entry,
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pull response header from the disk.
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string status_line(base::StringPrintf("HTTP/1.1 %d %s",
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             response.status_code,
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             response.status_text.c_str()));
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  status_line.push_back('\0');
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> headers(
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new net::HttpResponseHeaders(status_line));
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::map<std::string, std::string>::const_iterator it =
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           response.headers.begin();
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != response.headers.end(); ++it) {
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::string header;
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    header.reserve(it->first.size() + 2 + it->second.size());
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    header.append(it->first);
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    header.append(": ");
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    header.append(it->second);
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    headers->AddHeader(header);
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  http_response_info_.reset(new net::HttpResponseInfo());
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  http_response_info_->headers = headers;
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace content
218