Service Worker: in Unregister, wait until after the active worker no longer controls...
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_fetch_dispatcher.cc
blobcc920c253ba13d9ef33ebf4887148f435f523ceb
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.
5 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
7 #include "base/bind.h"
8 #include "content/browser/service_worker/service_worker_version.h"
9 #include "content/public/browser/resource_request_info.h"
10 #include "content/public/common/page_transition_types.h"
11 #include "net/url_request/url_request.h"
13 namespace content {
15 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
16 net::URLRequest* request,
17 ServiceWorkerVersion* version,
18 const FetchCallback& callback)
19 : version_(version),
20 callback_(callback),
21 weak_factory_(this) {
22 request_.url = request->url();
23 request_.method = request->method();
24 const net::HttpRequestHeaders& headers = request->extra_request_headers();
25 for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();)
26 request_.headers[it.name()] = it.value();
27 request_.referrer = GURL(request->referrer());
28 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
29 if (info) {
30 request_.is_reload = PageTransitionCoreTypeIs(info->GetPageTransition(),
31 PAGE_TRANSITION_RELOAD);
35 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {}
37 void ServiceWorkerFetchDispatcher::Run() {
38 DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING ||
39 version_->status() == ServiceWorkerVersion::ACTIVATED)
40 << version_->status();
42 if (version_->status() == ServiceWorkerVersion::ACTIVATING) {
43 version_->RegisterStatusChangeCallback(
44 base::Bind(&ServiceWorkerFetchDispatcher::DidWaitActivation,
45 weak_factory_.GetWeakPtr()));
46 return;
48 DispatchFetchEvent();
51 void ServiceWorkerFetchDispatcher::DidWaitActivation() {
52 if (version_->status() != ServiceWorkerVersion::ACTIVATED) {
53 DCHECK_EQ(ServiceWorkerVersion::INSTALLED, version_->status());
54 DidFailActivation();
55 return;
57 DispatchFetchEvent();
60 void ServiceWorkerFetchDispatcher::DidFailActivation() {
61 // The previous activation seems to have failed, abort the step
62 // with activate error. (The error should be separately reported
63 // to the associated documents and association must be dropped
64 // at this point)
65 DidFinish(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED,
66 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
67 ServiceWorkerResponse());
70 void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
71 version_->DispatchFetchEvent(
72 request_,
73 base::Bind(&ServiceWorkerFetchDispatcher::DidFinish,
74 weak_factory_.GetWeakPtr()));
77 void ServiceWorkerFetchDispatcher::DidFinish(
78 ServiceWorkerStatusCode status,
79 ServiceWorkerFetchEventResult fetch_result,
80 const ServiceWorkerResponse& response) {
81 DCHECK(!callback_.is_null());
82 FetchCallback callback = callback_;
83 callback.Run(status, fetch_result, response);
86 } // namespace content