Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_fetch_dispatcher.cc
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 "content/public/browser/resource_request_info.h"
10 #include "content/public/common/page_transition_types.h"
11 #include "net/url_request/url_request.h"
12
13 namespace content {
14
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);
32   }
33 }
34
35 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {}
36
37 void ServiceWorkerFetchDispatcher::Run() {
38   DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING ||
39          version_->status() == ServiceWorkerVersion::ACTIVATED)
40       << version_->status();
41
42   if (version_->status() == ServiceWorkerVersion::ACTIVATING) {
43     version_->RegisterStatusChangeCallback(
44         base::Bind(&ServiceWorkerFetchDispatcher::DidWaitActivation,
45                    weak_factory_.GetWeakPtr()));
46     return;
47   }
48   DispatchFetchEvent();
49 }
50
51 void ServiceWorkerFetchDispatcher::DidWaitActivation() {
52   if (version_->status() != ServiceWorkerVersion::ACTIVATED) {
53     DCHECK_EQ(ServiceWorkerVersion::INSTALLED, version_->status());
54     DidFailActivation();
55     return;
56   }
57   DispatchFetchEvent();
58 }
59
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());
68 }
69
70 void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
71   version_->DispatchFetchEvent(
72       request_,
73       base::Bind(&ServiceWorkerFetchDispatcher::DidFinish,
74                  weak_factory_.GetWeakPtr()));
75 }
76
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);
84 }
85
86 }  // namespace content