This source file includes following definitions.
- weak_factory_
- FallbackToNetwork
- ForwardToServiceWorker
- Start
- Kill
- GetLoadState
- GetCharset
- GetMimeType
- GetResponseInfo
- GetResponseCode
- SetExtraRequestHeaders
- ReadRawData
- http_info
- MaybeStartRequest
- StartRequest
- DidDispatchFetchEvent
- CreateResponseHeader
#include "content/browser/service_worker/service_worker_url_request_job.h"
#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_util.h"
namespace content {
ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
base::WeakPtr<ServiceWorkerProviderHost> provider_host)
: net::URLRequestJob(request, network_delegate),
provider_host_(provider_host),
response_type_(NOT_DETERMINED),
is_started_(false),
weak_factory_(this) {
}
void ServiceWorkerURLRequestJob::FallbackToNetwork() {
DCHECK_EQ(NOT_DETERMINED, response_type_);
response_type_ = FALLBACK_TO_NETWORK;
MaybeStartRequest();
}
void ServiceWorkerURLRequestJob::ForwardToServiceWorker() {
DCHECK_EQ(NOT_DETERMINED, response_type_);
response_type_ = FORWARD_TO_SERVICE_WORKER;
MaybeStartRequest();
}
void ServiceWorkerURLRequestJob::Start() {
is_started_ = true;
MaybeStartRequest();
}
void ServiceWorkerURLRequestJob::Kill() {
net::URLRequestJob::Kill();
fetch_dispatcher_.reset();
weak_factory_.InvalidateWeakPtrs();
}
net::LoadState ServiceWorkerURLRequestJob::GetLoadState() const {
return net::URLRequestJob::GetLoadState();
}
bool ServiceWorkerURLRequestJob::GetCharset(std::string* charset) {
if (!http_info())
return false;
return http_info()->headers->GetCharset(charset);
}
bool ServiceWorkerURLRequestJob::GetMimeType(std::string* mime_type) const {
if (!http_info())
return false;
return http_info()->headers->GetMimeType(mime_type);
}
void ServiceWorkerURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
if (!http_info())
return;
*info = *http_info();
}
int ServiceWorkerURLRequestJob::GetResponseCode() const {
if (!http_info())
return -1;
return http_info()->headers->response_code();
}
void ServiceWorkerURLRequestJob::SetExtraRequestHeaders(
const net::HttpRequestHeaders& headers) {
std::string range_header;
std::vector<net::HttpByteRange> ranges;
if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header) ||
!net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
return;
}
if (ranges.size() == 1U)
byte_range_ = ranges[0];
}
bool ServiceWorkerURLRequestJob::ReadRawData(
net::IOBuffer* buf, int buf_size, int *bytes_read) {
NOTIMPLEMENTED();
*bytes_read = 0;
return true;
}
const net::HttpResponseInfo* ServiceWorkerURLRequestJob::http_info() const {
if (!http_response_info_)
return NULL;
if (range_response_info_)
return range_response_info_.get();
return http_response_info_.get();
}
ServiceWorkerURLRequestJob::~ServiceWorkerURLRequestJob() {
}
void ServiceWorkerURLRequestJob::MaybeStartRequest() {
if (is_started_ && response_type_ != NOT_DETERMINED) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&ServiceWorkerURLRequestJob::StartRequest,
weak_factory_.GetWeakPtr()));
}
}
void ServiceWorkerURLRequestJob::StartRequest() {
switch (response_type_) {
case NOT_DETERMINED:
NOTREACHED();
return;
case FALLBACK_TO_NETWORK:
NotifyRestartRequired();
return;
case FORWARD_TO_SERVICE_WORKER:
DCHECK(provider_host_ && provider_host_->associated_version());
DCHECK(!fetch_dispatcher_);
fetch_dispatcher_.reset(new ServiceWorkerFetchDispatcher(
request(), provider_host_->associated_version(),
base::Bind(&ServiceWorkerURLRequestJob::DidDispatchFetchEvent,
weak_factory_.GetWeakPtr())));
fetch_dispatcher_->Run();
return;
}
NOTREACHED();
}
void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
ServiceWorkerStatusCode status,
ServiceWorkerFetchEventResult fetch_result,
const ServiceWorkerResponse& response) {
fetch_dispatcher_.reset();
if (!request())
return;
if (status != SERVICE_WORKER_OK) {
response_type_ = FALLBACK_TO_NETWORK;
NotifyRestartRequired();
}
if (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK) {
response_type_ = FALLBACK_TO_NETWORK;
NotifyRestartRequired();
return;
}
DCHECK_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, fetch_result);
CreateResponseHeader(response);
NotifyHeadersComplete();
}
void ServiceWorkerURLRequestJob::CreateResponseHeader(
const ServiceWorkerResponse& response) {
std::string status_line(base::StringPrintf("HTTP/1.1 %d %s",
response.status_code,
response.status_text.c_str()));
status_line.push_back('\0');
scoped_refptr<net::HttpResponseHeaders> headers(
new net::HttpResponseHeaders(status_line));
for (std::map<std::string, std::string>::const_iterator it =
response.headers.begin();
it != response.headers.end(); ++it) {
std::string header;
header.reserve(it->first.size() + 2 + it->second.size());
header.append(it->first);
header.append(": ");
header.append(it->second);
headers->AddHeader(header);
}
http_response_info_.reset(new net::HttpResponseInfo());
http_response_info_->headers = headers;
}
}