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