1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" 6 7 #include "base/bind.h" 8 #include "content/browser/service_worker/service_worker_version.h" 9 #include "net/url_request/url_request.h" 10 11 namespace content { 12 13 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher( 14 net::URLRequest* request, 15 ServiceWorkerVersion* version, 16 const FetchCallback& callback) 17 : version_(version), 18 callback_(callback), 19 weak_factory_(this) { 20 request_.url = request->url(); 21 request_.method = request->method(); 22 const net::HttpRequestHeaders& headers = request->extra_request_headers(); 23 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) 24 request_.headers[it.name()] = it.value(); 25 } 26 27 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {} 28 29 void ServiceWorkerFetchDispatcher::Run() { 30 DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING || 31 version_->status() == ServiceWorkerVersion::ACTIVE) 32 << version_->status(); 33 34 if (version_->status() == ServiceWorkerVersion::ACTIVATING) { 35 version_->RegisterStatusChangeCallback( 36 base::Bind(&ServiceWorkerFetchDispatcher::DidWaitActivation, 37 weak_factory_.GetWeakPtr())); 38 return; 39 } 40 DispatchFetchEvent(); 41 } 42 43 void ServiceWorkerFetchDispatcher::DidWaitActivation() { 44 if (version_->status() != ServiceWorkerVersion::ACTIVE) { 45 DCHECK_EQ(ServiceWorkerVersion::INSTALLED, version_->status()); 46 DidFailActivation(); 47 return; 48 } 49 DispatchFetchEvent(); 50 } 51 52 void ServiceWorkerFetchDispatcher::DidFailActivation() { 53 // The previous activation seems to have failed, abort the step 54 // with activate error. (The error should be separately reported 55 // to the associated documents and association must be dropped 56 // at this point) 57 DidFinish(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED, 58 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, 59 ServiceWorkerResponse()); 60 } 61 62 void ServiceWorkerFetchDispatcher::DispatchFetchEvent() { 63 version_->DispatchFetchEvent( 64 request_, 65 base::Bind(&ServiceWorkerFetchDispatcher::DidFinish, 66 weak_factory_.GetWeakPtr())); 67 } 68 69 void ServiceWorkerFetchDispatcher::DidFinish( 70 ServiceWorkerStatusCode status, 71 ServiceWorkerFetchEventResult fetch_result, 72 const ServiceWorkerResponse& response) { 73 DCHECK(!callback_.is_null()); 74 FetchCallback callback = callback_; 75 callback.Run(status, fetch_result, response); 76 } 77 78 } // namespace content 79