blob: cc920c253ba13d9ef33ebf4887148f435f523ceb [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
#include "base/bind.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/page_transition_types.h"
#include "net/url_request/url_request.h"
namespace content {
ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
net::URLRequest* request,
ServiceWorkerVersion* version,
const FetchCallback& callback)
: version_(version),
callback_(callback),
weak_factory_(this) {
request_.url = request->url();
request_.method = request->method();
const net::HttpRequestHeaders& headers = request->extra_request_headers();
for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();)
request_.headers[it.name()] = it.value();
request_.referrer = GURL(request->referrer());
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
if (info) {
request_.is_reload = PageTransitionCoreTypeIs(info->GetPageTransition(),
PAGE_TRANSITION_RELOAD);
}
}
ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {}
void ServiceWorkerFetchDispatcher::Run() {
DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING ||
version_->status() == ServiceWorkerVersion::ACTIVATED)
<< version_->status();
if (version_->status() == ServiceWorkerVersion::ACTIVATING) {
version_->RegisterStatusChangeCallback(
base::Bind(&ServiceWorkerFetchDispatcher::DidWaitActivation,
weak_factory_.GetWeakPtr()));
return;
}
DispatchFetchEvent();
}
void ServiceWorkerFetchDispatcher::DidWaitActivation() {
if (version_->status() != ServiceWorkerVersion::ACTIVATED) {
DCHECK_EQ(ServiceWorkerVersion::INSTALLED, version_->status());
DidFailActivation();
return;
}
DispatchFetchEvent();
}
void ServiceWorkerFetchDispatcher::DidFailActivation() {
// The previous activation seems to have failed, abort the step
// with activate error. (The error should be separately reported
// to the associated documents and association must be dropped
// at this point)
DidFinish(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED,
SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
ServiceWorkerResponse());
}
void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
version_->DispatchFetchEvent(
request_,
base::Bind(&ServiceWorkerFetchDispatcher::DidFinish,
weak_factory_.GetWeakPtr()));
}
void ServiceWorkerFetchDispatcher::DidFinish(
ServiceWorkerStatusCode status,
ServiceWorkerFetchEventResult fetch_result,
const ServiceWorkerResponse& response) {
DCHECK(!callback_.is_null());
FetchCallback callback = callback_;
callback.Run(status, fetch_result, response);
}
} // namespace content