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" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "webkit/browser/blob/blob_data_handle.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "webkit/browser/blob/blob_storage_context.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "webkit/browser/blob/blob_url_request_job_factory.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob( 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request, 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::NetworkDelegate* network_delegate, 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<ServiceWorkerProviderHost> provider_host, 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) provider_host_(provider_host), 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_(NOT_DETERMINED), 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_started_(false), 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context_(blob_storage_context), 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_(this) { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::FallbackToNetwork() { 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(NOT_DETERMINED, response_type_); 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FALLBACK_TO_NETWORK; 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeStartRequest(); 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::ForwardToServiceWorker() { 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(NOT_DETERMINED, response_type_); 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FORWARD_TO_SERVICE_WORKER; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeStartRequest(); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::Start() { 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_started_ = true; 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MaybeStartRequest(); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::Kill() { 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestJob::Kill(); 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_.reset(); 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_.reset(); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_.InvalidateWeakPtrs(); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const { 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): refine this for better debug. 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return net::URLRequestJob::GetLoadState(); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) { 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_info()->headers->GetCharset(charset); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const { 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_info()->headers->GetMimeType(mime_type); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) { 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *info = *http_info(); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int ServiceWorkerURLRequestJob::GetResponseCode() const { 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_info()) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return -1; 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_info()->headers->response_code(); 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::SetExtraRequestHeaders( 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const net::HttpRequestHeaders& headers) { 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string range_header; 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<net::HttpByteRange> ranges; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header) || 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We don't support multiple range requests in one single URL request. 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ranges.size() == 1U) 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) byte_range_ = ranges[0]; 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServiceWorkerURLRequestJob::ReadRawData( 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::IOBuffer* buf, int buf_size, int *bytes_read) { 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!blob_request_) { 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *bytes_read = 0; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_->Read(buf, buf_size, bytes_read); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequestStatus status = blob_request_->status(); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetStatus(status); 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (status.is_io_pending()) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return status.is_success(); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnReceivedRedirect(net::URLRequest* request, 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GURL& new_url, 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool* defer_redirect) { 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnAuthRequired( 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest* request, 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::AuthChallengeInfo* auth_info) { 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnCertificateRequested( 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest* request, 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::SSLCertRequestInfo* cert_request_info) { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnSSLCertificateError( 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::URLRequest* request, 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const net::SSLInfo& ssl_info, 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool fatal) { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnBeforeNetworkStart(net::URLRequest* request, 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool* defer) { 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED(); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnResponseStarted(net::URLRequest* request) { 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(falken): Add Content-Length, Content-Type if they were not provided in 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the ServiceWorkerResponse. 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommitResponseHeader(); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::OnReadCompleted(net::URLRequest* request, 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int bytes_read) { 154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SetStatus(request->status()); 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!request->status().is_success()) { 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyDone(request->status()); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyReadComplete(bytes_read); 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (bytes_read == 0) 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyDone(request->status()); 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const { 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!http_response_info_) 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (range_response_info_) 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return range_response_info_.get(); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return http_response_info_.get(); 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() { 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::MaybeStartRequest() { 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_started_ && response_type_ != NOT_DETERMINED) { 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start asynchronously. 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoop::current()->PostTask( 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ServiceWorkerURLRequestJob::StartRequest, 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_.GetWeakPtr())); 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::StartRequest() { 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (response_type_) { 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case NOT_DETERMINED: 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case FALLBACK_TO_NETWORK: 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Restart the request to create a new job. Our request handler will 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // return NULL, and the default job (which will hit network) should be 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // created. 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NotifyRestartRequired(); 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case FORWARD_TO_SERVICE_WORKER: 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(provider_host_ && provider_host_->active_version()); 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!fetch_dispatcher_); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Send a fetch event to the ServiceWorker associated to the 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // provider_host. 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher( 205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch request(), provider_host_->active_version(), 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent, 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_factory_.GetWeakPtr()))); 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_->Run(); 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::DidDispatchFetchEvent( 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerStatusCode status, 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerFetchEventResult fetch_result, 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ServiceWorkerResponse& response) { 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetch_dispatcher_.reset(); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Check if we're not orphaned. 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!request()) 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (status != SERVICE_WORKER_OK) { 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatching event has been failed, falling back to the network. 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (Tentative behavior described on github) 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): consider returning error if we've come here because 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // unexpected worker termination etc (so that we could fix bugs). 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): Would be nice to log the error case. 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FALLBACK_TO_NETWORK; 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NotifyRestartRequired(); 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) { 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Change the response type and restart the request to fallback to 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the network. 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response_type_ = FALLBACK_TO_NETWORK; 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NotifyRestartRequired(); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We should have a response now. 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Set up a request for reading the blob. 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!response.blob_uuid.empty() && blob_storage_context_) { 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<webkit_blob::BlobDataHandle> blob_data_handle = 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_storage_context_->GetBlobDataFromUUID(response.blob_uuid); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!blob_data_handle) { 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The renderer gave us a bad blob UUID. 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DeliverErrorResponse(); 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_ = webkit_blob::BlobProtocolHandler::CreateBlobRequest( 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_data_handle.Pass(), request()->context(), this); 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) blob_request_->Start(); 259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateResponseHeader( 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) response.status_code, response.status_text, response.headers); 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!blob_request_) 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommitResponseHeader(); 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerURLRequestJob::CreateResponseHeader( 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int status_code, 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& status_text, 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::map<std::string, std::string>& headers) { 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(kinuko): If the response has an identifier to on-disk cache entry, 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // pull response header from the disk. 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string status_line( 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::StringPrintf("HTTP/1.1 %d %s", status_code, status_text.c_str())); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) status_line.push_back('\0'); 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_response_headers_ = new net::HttpResponseHeaders(status_line); 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::map<std::string, std::string>::const_iterator it = headers.begin(); 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != headers.end(); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string header; 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.reserve(it->first.size() + 2 + it->second.size()); 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.append(it->first); 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.append(": "); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) header.append(it->second); 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_response_headers_->AddHeader(header); 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::CommitResponseHeader() { 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) http_response_info_.reset(new net::HttpResponseInfo()); 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) http_response_info_->headers.swap(http_response_headers_); 292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyHeadersComplete(); 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceWorkerURLRequestJob::DeliverErrorResponse() { 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(falken): Print an error to the console of the ServiceWorker and of 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the requesting page. 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CreateResponseHeader(500, 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "Service Worker Response Error", 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::map<std::string, std::string>()); 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CommitResponseHeader(); 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace content 305