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) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <map> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <string> 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <vector> 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/guid.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/stringprintf.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/time/time.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_fetch_dispatcher.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/service_worker/service_worker_provider_host.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/common/resource_request_body.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/common/service_worker/service_worker_types.h" 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/browser/blob_handle.h" 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/browser/resource_request_info.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_errors.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_request_headers.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_response_headers.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_response_info.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_util.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_data_handle.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_url_request_job_factory.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h" 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request, 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::NetworkDelegate* network_delegate, 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<ServiceWorkerProviderHost> provider_host, 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<storage::BlobStorageContext> blob_storage_context, 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<ResourceRequestBody> body) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) provider_host_(provider_host), 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_(NOT_DETERMINED), 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_started_(false), 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context_(blob_storage_context), 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) body_(body), 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_(this) { 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::FallbackToNetwork() { 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(NOT_DETERMINED, response_type_); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FALLBACK_TO_NETWORK; 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeStartRequest(); 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(NOT_DETERMINED, response_type_); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FORWARD_TO_SERVICE_WORKER; 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeStartRequest(); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::Start() { 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_started_ = true; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeStartRequest(); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::Kill() { 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestJob::Kill(); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_.reset(); 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_.reset(); 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): refine this for better debug. 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return net::URLRequestJob::GetLoadState(); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) { 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_info()->headers->GetCharset(charset); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const { 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_info()->headers->GetMimeType(mime_type); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *info = *http_info(); 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci info->response_time = response_time_; 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerURLRequestJob::GetLoadTimingInfo( 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::LoadTimingInfo* load_timing_info) const { 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *load_timing_info = load_timing_info_; 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int ServiceWorkerURLRequestJob::GetResponseCode() const { 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return -1; 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_info()->headers->response_code(); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::SetExtraRequestHeaders( 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string range_header; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header) || 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We don't support multiple range requests in one single URL request. 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ranges.size() == 1U) 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) byte_range_ = ranges[0]; 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::ReadRawData( 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::IOBuffer* buf, int buf_size, int *bytes_read) { 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!blob_request_) { 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *bytes_read = 0; 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_->Read(buf, buf_size, bytes_read); 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequestStatus status = blob_request_->status(); 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetStatus(status); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status.is_io_pending()) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status.is_success(); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnReceivedRedirect( 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) net::URLRequest* request, 1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const net::RedirectInfo& redirect_info, 1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool* defer_redirect) { 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnAuthRequired( 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest* request, 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::AuthChallengeInfo* auth_info) { 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnCertificateRequested( 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest* request, 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::SSLCertRequestInfo* cert_request_info) { 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnSSLCertificateError( 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest* request, 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const net::SSLInfo& ssl_info, 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool fatal) { 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnBeforeNetworkStart(net::URLRequest* request, 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool* defer) { 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(falken): Add Content-Length, Content-Type if they were not provided in 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the ServiceWorkerResponse. 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response_time_ = base::Time::Now(); 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommitResponseHeader(); 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int bytes_read) { 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SetStatus(request->status()); 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!request->status().is_success()) { 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyDone(request->status()); 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyReadComplete(bytes_read); 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (bytes_read == 0) 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyDone(request->status()); 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_response_info_) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (range_response_info_) 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return range_response_info_.get(); 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_response_info_.get(); 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerURLRequestJob::GetExtraResponseInfo( 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool* was_fetched_via_service_worker, 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL* original_url_via_service_worker, 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks* fetch_start_time, 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks* fetch_ready_time, 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks* fetch_end_time) const { 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (response_type_ != FORWARD_TO_SERVICE_WORKER) { 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *was_fetched_via_service_worker = false; 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *original_url_via_service_worker = GURL(); 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *was_fetched_via_service_worker = true; 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *original_url_via_service_worker = response_url_; 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *fetch_start_time = fetch_start_time_; 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *fetch_ready_time = fetch_ready_time_; 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *fetch_end_time = fetch_end_time_; 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() { 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::MaybeStartRequest() { 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_started_ && response_type_ != NOT_DETERMINED) { 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start asynchronously. 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoop::current()->PostTask( 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ServiceWorkerURLRequestJob::StartRequest, 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_.GetWeakPtr())); 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::StartRequest() { 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (response_type_) { 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case NOT_DETERMINED: 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case FALLBACK_TO_NETWORK: 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Restart the request to create a new job. Our request handler will 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // return NULL, and the default job (which will hit network) should be 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // created. 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NotifyRestartRequired(); 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case FORWARD_TO_SERVICE_WORKER: 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(provider_host_ && provider_host_->active_version()); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!fetch_dispatcher_); 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Send a fetch event to the ServiceWorker associated to the 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // provider_host. 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CreateFetchRequest(), 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) provider_host_->active_version(), 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ServiceWorkerURLRequestJob::DidPrepareFetchEvent, 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.GetWeakPtr()), 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_.GetWeakPtr()))); 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fetch_start_time_ = base::TimeTicks::Now(); 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci load_timing_info_.send_start = fetch_start_time_; 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_->Run(); 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<ServiceWorkerFetchRequest> 26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)ServiceWorkerURLRequestJob::CreateFetchRequest() { 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string blob_uuid; 26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint64 blob_size = 0; 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CreateRequestBodyBlob(&blob_uuid, &blob_size); 26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<ServiceWorkerFetchRequest> request( 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new ServiceWorkerFetchRequest()); 26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request->url = request_->url(); 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request->method = request_->method(); 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const net::HttpRequestHeaders& headers = request_->extra_request_headers(); 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request->headers[it.name()] = it.value(); 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request->blob_uuid = blob_uuid; 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request->blob_size = blob_size; 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request->referrer = GURL(request_->referrer()); 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_); 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (info) { 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->is_reload = ui::PageTransitionCoreTypeIs( 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci info->GetPageTransition(), ui::PAGE_TRANSITION_RELOAD); 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return request.Pass(); 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ServiceWorkerURLRequestJob::CreateRequestBodyBlob(std::string* blob_uuid, 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint64* blob_size) { 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!body_.get() || !blob_storage_context_) 28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<const ResourceRequestBody::Element*> resolved_elements; 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < body_->elements()->size(); ++i) { 29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ResourceRequestBody::Element& element = (*body_->elements())[i]; 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (element.type() != ResourceRequestBody::Element::TYPE_BLOB) { 29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) resolved_elements.push_back(&element); 29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) continue; 29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::BlobDataHandle> handle = 29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) blob_storage_context_->GetBlobDataFromUUID(element.blob_uuid()); 29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (handle->data()->items().empty()) 29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) continue; 30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < handle->data()->items().size(); ++i) { 30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::BlobData::Item& item = handle->data()->items().at(i); 30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK_NE(storage::BlobData::Item::TYPE_BLOB, item.type()); 30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) resolved_elements.push_back(&item); 30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string uuid(base::GenerateGUID()); 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint64 total_size = 0; 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::BlobData> blob_data = new storage::BlobData(uuid); 31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < resolved_elements.size(); ++i) { 31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const ResourceRequestBody::Element& element = *resolved_elements[i]; 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (total_size != kuint64max && element.length() != kuint64max) 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_size += element.length(); 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_size = kuint64max; 31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) switch (element.type()) { 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ResourceRequestBody::Element::TYPE_BYTES: 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) blob_data->AppendData(element.bytes(), element.length()); 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ResourceRequestBody::Element::TYPE_FILE: 32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) blob_data->AppendFile(element.path(), 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) element.offset(), 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) element.length(), 32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) element.expected_modification_time()); 32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ResourceRequestBody::Element::TYPE_BLOB: 32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Blob elements should be resolved beforehand. 32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NOTREACHED(); 32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ResourceRequestBody::Element::TYPE_FILE_FILESYSTEM: 33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) blob_data->AppendFileSystemFile(element.filesystem_url(), 33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) element.offset(), 33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) element.length(), 33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) element.expected_modification_time()); 33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 33603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) default: 33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NOTIMPLEMENTED(); 33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request_body_blob_data_handle_ = 34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) blob_storage_context_->AddFinishedBlob(blob_data.get()); 34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *blob_uuid = uuid; 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *blob_size = total_size; 34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerURLRequestJob::DidPrepareFetchEvent() { 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fetch_ready_time_ = base::TimeTicks::Now(); 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerStatusCode status, 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerFetchEventResult fetch_result, 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ServiceWorkerResponse& response) { 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_.reset(); 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Check if we're not orphaned. 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!request()) 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (status != SERVICE_WORKER_OK) { 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatching event has been failed, falling back to the network. 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (Tentative behavior described on github) 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): consider returning error if we've come here because 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // unexpected worker termination etc (so that we could fix bugs). 367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): Would be nice to log the error case. 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FALLBACK_TO_NETWORK; 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NotifyRestartRequired(); 370010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Change the response type and restart the request to fallback to 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the network. 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FALLBACK_TO_NETWORK; 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NotifyRestartRequired(); 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We should have a response now. 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Treat a response whose status is 0 as a Network Error. 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (response.status_code == 0) { 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyDone( 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fetch_end_time_ = base::TimeTicks::Now(); 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci load_timing_info_.send_end = fetch_end_time_; 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Set up a request for reading the blob. 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!response.blob_uuid.empty() && blob_storage_context_) { 39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::BlobDataHandle> blob_data_handle = 397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!blob_data_handle) { 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The renderer gave us a bad blob UUID. 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DeliverErrorResponse(); 401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) blob_request_ = storage::BlobProtocolHandler::CreateBlobRequest( 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_data_handle.Pass(), request()->context(), this); 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_->Start(); 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) response_url_ = response.url; 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateResponseHeader( 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) response.status_code, response.status_text, response.headers); 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci load_timing_info_.receive_headers_end = base::TimeTicks::Now(); 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!blob_request_) 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommitResponseHeader(); 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::CreateResponseHeader( 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int status_code, 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& status_text, 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ServiceWorkerHeaderMap& headers) { 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): If the response has an identifier to on-disk cache entry, 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // pull response header from the disk. 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string status_line( 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::StringPrintf("HTTP/1.1 %d %s", status_code, status_text.c_str())); 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) status_line.push_back('\0'); 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_response_headers_ = new net::HttpResponseHeaders(status_line); 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (ServiceWorkerHeaderMap::const_iterator it = headers.begin(); 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != headers.end(); 428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string header; 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.reserve(it->first.size() + 2 + it->second.size()); 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.append(it->first); 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.append(": "); 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.append(it->second); 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_response_headers_->AddHeader(header); 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::CommitResponseHeader() { 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) http_response_info_.reset(new net::HttpResponseInfo()); 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_response_info_->headers.swap(http_response_headers_); 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyHeadersComplete(); 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::DeliverErrorResponse() { 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(falken): Print an error to the console of the ServiceWorker and of 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the requesting page. 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CreateResponseHeader( 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 500, "Service Worker Response Error", ServiceWorkerHeaderMap()); 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommitResponseHeader(); 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace content 453