Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Unified Diff: webkit/browser/appcache/appcache_url_request_job.cc

Issue 344493002: Move all remaining appcache-related code to content namespace (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webkit/browser/appcache/appcache_url_request_job.cc
diff --git a/webkit/browser/appcache/appcache_url_request_job.cc b/webkit/browser/appcache/appcache_url_request_job.cc
deleted file mode 100644
index 2cdcb779a50bf4689d49ba3832ea5b04fc7e0731..0000000000000000000000000000000000000000
--- a/webkit/browser/appcache/appcache_url_request_job.cc
+++ /dev/null
@@ -1,449 +0,0 @@
-// Copyright (c) 2012 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 "webkit/browser/appcache/appcache_url_request_job.h"
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_util.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_status.h"
-#include "webkit/browser/appcache/appcache.h"
-#include "webkit/browser/appcache/appcache_group.h"
-#include "webkit/browser/appcache/appcache_histograms.h"
-#include "webkit/browser/appcache/appcache_host.h"
-#include "webkit/browser/appcache/appcache_service_impl.h"
-
-namespace appcache {
-
-AppCacheURLRequestJob::AppCacheURLRequestJob(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- AppCacheStorage* storage,
- AppCacheHost* host,
- bool is_main_resource)
- : net::URLRequestJob(request, network_delegate),
- host_(host),
- storage_(storage),
- has_been_started_(false), has_been_killed_(false),
- delivery_type_(AWAITING_DELIVERY_ORDERS),
- group_id_(0), cache_id_(kAppCacheNoCacheId), is_fallback_(false),
- is_main_resource_(is_main_resource),
- cache_entry_not_found_(false),
- weak_factory_(this) {
- DCHECK(storage_);
-}
-
-void AppCacheURLRequestJob::DeliverAppCachedResponse(
- const GURL& manifest_url, int64 group_id, int64 cache_id,
- const AppCacheEntry& entry, bool is_fallback) {
- DCHECK(!has_delivery_orders());
- DCHECK(entry.has_response_id());
- delivery_type_ = APPCACHED_DELIVERY;
- manifest_url_ = manifest_url;
- group_id_ = group_id;
- cache_id_ = cache_id;
- entry_ = entry;
- is_fallback_ = is_fallback;
- MaybeBeginDelivery();
-}
-
-void AppCacheURLRequestJob::DeliverNetworkResponse() {
- DCHECK(!has_delivery_orders());
- delivery_type_ = NETWORK_DELIVERY;
- storage_ = NULL; // not needed
- MaybeBeginDelivery();
-}
-
-void AppCacheURLRequestJob::DeliverErrorResponse() {
- DCHECK(!has_delivery_orders());
- delivery_type_ = ERROR_DELIVERY;
- storage_ = NULL; // not needed
- MaybeBeginDelivery();
-}
-
-void AppCacheURLRequestJob::MaybeBeginDelivery() {
- if (has_been_started() && has_delivery_orders()) {
- // Start asynchronously so that all error reporting and data
- // callbacks happen as they would for network requests.
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&AppCacheURLRequestJob::BeginDelivery,
- weak_factory_.GetWeakPtr()));
- }
-}
-
-void AppCacheURLRequestJob::BeginDelivery() {
- DCHECK(has_delivery_orders() && has_been_started());
-
- if (has_been_killed())
- return;
-
- switch (delivery_type_) {
- case NETWORK_DELIVERY:
- AppCacheHistograms::AddNetworkJobStartDelaySample(
- base::TimeTicks::Now() - start_time_tick_);
- // To fallthru to the network, we restart the request which will
- // cause a new job to be created to retrieve the resource from the
- // network. Our caller is responsible for arranging to not re-intercept
- // the same request.
- NotifyRestartRequired();
- break;
-
- case ERROR_DELIVERY:
- AppCacheHistograms::AddErrorJobStartDelaySample(
- base::TimeTicks::Now() - start_time_tick_);
- request()->net_log().AddEvent(
- net::NetLog::TYPE_APPCACHE_DELIVERING_ERROR_RESPONSE);
- NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
- net::ERR_FAILED));
- break;
-
- case APPCACHED_DELIVERY:
- if (entry_.IsExecutable()) {
- BeginExecutableHandlerDelivery();
- return;
- }
- AppCacheHistograms::AddAppCacheJobStartDelaySample(
- base::TimeTicks::Now() - start_time_tick_);
- request()->net_log().AddEvent(
- is_fallback_ ?
- net::NetLog::TYPE_APPCACHE_DELIVERING_FALLBACK_RESPONSE :
- net::NetLog::TYPE_APPCACHE_DELIVERING_CACHED_RESPONSE);
- storage_->LoadResponseInfo(
- manifest_url_, group_id_, entry_.response_id(), this);
- break;
-
- default:
- NOTREACHED();
- break;
- }
-}
-
-void AppCacheURLRequestJob::BeginExecutableHandlerDelivery() {
- DCHECK(CommandLine::ForCurrentProcess()->
- HasSwitch(kEnableExecutableHandlers));
- if (!storage_->service()->handler_factory()) {
- BeginErrorDelivery("missing handler factory");
- return;
- }
-
- request()->net_log().AddEvent(
- net::NetLog::TYPE_APPCACHE_DELIVERING_EXECUTABLE_RESPONSE);
-
- // We defer job delivery until the executable handler is spun up and
- // provides a response. The sequence goes like this...
- //
- // 1. First we load the cache.
- // 2. Then if the handler is not spun up, we load the script resource which
- // is needed to spin it up.
- // 3. Then we ask then we ask the handler to compute a response.
- // 4. Finally we deilver that response to the caller.
- storage_->LoadCache(cache_id_, this);
-}
-
-void AppCacheURLRequestJob::OnCacheLoaded(AppCache* cache, int64 cache_id) {
- DCHECK_EQ(cache_id_, cache_id);
- DCHECK(!has_been_killed());
-
- if (!cache) {
- BeginErrorDelivery("cache load failed");
- return;
- }
-
- // Keep references to ensure they don't go out of scope until job completion.
- cache_ = cache;
- group_ = cache->owning_group();
-
- // If the handler is spun up, ask it to compute a response.
- AppCacheExecutableHandler* handler =
- cache->GetExecutableHandler(entry_.response_id());
- if (handler) {
- InvokeExecutableHandler(handler);
- return;
- }
-
- // Handler is not spun up yet, load the script resource to do that.
- // NOTE: This is not ideal since multiple jobs may be doing this,
- // concurrently but close enough for now, the first to load the script
- // will win.
-
- // Read the script data, truncating if its too large.
- // NOTE: we just issue one read and don't bother chaining if the resource
- // is very (very) large, close enough for now.
- const int64 kLimit = 500 * 1000;
- handler_source_buffer_ = new net::GrowableIOBuffer();
- handler_source_buffer_->SetCapacity(kLimit);
- handler_source_reader_.reset(storage_->CreateResponseReader(
- manifest_url_, group_id_, entry_.response_id()));
- handler_source_reader_->ReadData(
- handler_source_buffer_.get(),
- kLimit,
- base::Bind(&AppCacheURLRequestJob::OnExecutableSourceLoaded,
- base::Unretained(this)));
-}
-
-void AppCacheURLRequestJob::OnExecutableSourceLoaded(int result) {
- DCHECK(!has_been_killed());
- handler_source_reader_.reset();
- if (result < 0) {
- BeginErrorDelivery("script source load failed");
- return;
- }
-
- handler_source_buffer_->SetCapacity(result); // Free up some memory.
-
- AppCacheExecutableHandler* handler = cache_->GetOrCreateExecutableHandler(
- entry_.response_id(), handler_source_buffer_.get());
- handler_source_buffer_ = NULL; // not needed anymore
- if (handler) {
- InvokeExecutableHandler(handler);
- return;
- }
-
- BeginErrorDelivery("factory failed to produce a handler");
-}
-
-void AppCacheURLRequestJob::InvokeExecutableHandler(
- AppCacheExecutableHandler* handler) {
- handler->HandleRequest(
- request(),
- base::Bind(&AppCacheURLRequestJob::OnExecutableResponseCallback,
- weak_factory_.GetWeakPtr()));
-}
-
-void AppCacheURLRequestJob::OnExecutableResponseCallback(
- const AppCacheExecutableHandler::Response& response) {
- DCHECK(!has_been_killed());
- if (response.use_network) {
- delivery_type_ = NETWORK_DELIVERY;
- storage_ = NULL;
- BeginDelivery();
- return;
- }
-
- if (!response.cached_resource_url.is_empty()) {
- AppCacheEntry* entry_ptr = cache_->GetEntry(response.cached_resource_url);
- if (entry_ptr && !entry_ptr->IsExecutable()) {
- entry_ = *entry_ptr;
- BeginDelivery();
- return;
- }
- }
-
- if (!response.redirect_url.is_empty()) {
- // TODO(michaeln): playback a redirect
- // response_headers_(new HttpResponseHeaders(response_headers)),
- // fallthru for now to deliver an error
- }
-
- // Otherwise, return an error.
- BeginErrorDelivery("handler returned an invalid response");
-}
-
-void AppCacheURLRequestJob::BeginErrorDelivery(const char* message) {
- if (host_)
- host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR,
- message);
- delivery_type_ = ERROR_DELIVERY;
- storage_ = NULL;
- BeginDelivery();
-}
-
-AppCacheURLRequestJob::~AppCacheURLRequestJob() {
- if (storage_)
- storage_->CancelDelegateCallbacks(this);
-}
-
-void AppCacheURLRequestJob::OnResponseInfoLoaded(
- AppCacheResponseInfo* response_info, int64 response_id) {
- DCHECK(is_delivering_appcache_response());
- scoped_refptr<AppCacheURLRequestJob> protect(this);
- if (response_info) {
- info_ = response_info;
- reader_.reset(storage_->CreateResponseReader(
- manifest_url_, group_id_, entry_.response_id()));
-
- if (is_range_request())
- SetupRangeResponse();
-
- NotifyHeadersComplete();
- } else {
- if (storage_->service()->storage() == storage_) {
- // A resource that is expected to be in the appcache is missing.
- // See http://code.google.com/p/chromium/issues/detail?id=50657
- // Instead of failing the request, we restart the request. The retry
- // attempt will fallthru to the network instead of trying to load
- // from the appcache.
- storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_,
- entry_.response_id());
- AppCacheHistograms::CountResponseRetrieval(
- false, is_main_resource_, manifest_url_.GetOrigin());
- }
- cache_entry_not_found_ = true;
- NotifyRestartRequired();
- }
-}
-
-const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const {
- if (!info_.get())
- return NULL;
- if (range_response_info_)
- return range_response_info_.get();
- return info_->http_response_info();
-}
-
-void AppCacheURLRequestJob::SetupRangeResponse() {
- DCHECK(is_range_request() && info_.get() && reader_.get() &&
- is_delivering_appcache_response());
- int resource_size = static_cast<int>(info_->response_data_size());
- if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) {
- range_requested_ = net::HttpByteRange();
- return;
- }
-
- DCHECK(range_requested_.IsValid());
- int offset = static_cast<int>(range_requested_.first_byte_position());
- int length = static_cast<int>(range_requested_.last_byte_position() -
- range_requested_.first_byte_position() + 1);
-
- // Tell the reader about the range to read.
- reader_->SetReadRange(offset, length);
-
- // Make a copy of the full response headers and fix them up
- // for the range we'll be returning.
- range_response_info_.reset(
- new net::HttpResponseInfo(*info_->http_response_info()));
- net::HttpResponseHeaders* headers = range_response_info_->headers.get();
- headers->UpdateWithNewRange(
- range_requested_, resource_size, true /* replace status line */);
-}
-
-void AppCacheURLRequestJob::OnReadComplete(int result) {
- DCHECK(is_delivering_appcache_response());
- if (result == 0) {
- NotifyDone(net::URLRequestStatus());
- AppCacheHistograms::CountResponseRetrieval(
- true, is_main_resource_, manifest_url_.GetOrigin());
- } else if (result < 0) {
- if (storage_->service()->storage() == storage_) {
- storage_->service()->CheckAppCacheResponse(manifest_url_, cache_id_,
- entry_.response_id());
- }
- NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, result));
- AppCacheHistograms::CountResponseRetrieval(
- false, is_main_resource_, manifest_url_.GetOrigin());
- } else {
- SetStatus(net::URLRequestStatus()); // Clear the IO_PENDING status
- }
- NotifyReadComplete(result);
-}
-
-// net::URLRequestJob overrides ------------------------------------------------
-
-void AppCacheURLRequestJob::Start() {
- DCHECK(!has_been_started());
- has_been_started_ = true;
- start_time_tick_ = base::TimeTicks::Now();
- MaybeBeginDelivery();
-}
-
-void AppCacheURLRequestJob::Kill() {
- if (!has_been_killed_) {
- has_been_killed_ = true;
- reader_.reset();
- handler_source_reader_.reset();
- if (storage_) {
- storage_->CancelDelegateCallbacks(this);
- storage_ = NULL;
- }
- host_ = NULL;
- info_ = NULL;
- cache_ = NULL;
- group_ = NULL;
- range_response_info_.reset();
- net::URLRequestJob::Kill();
- weak_factory_.InvalidateWeakPtrs();
- }
-}
-
-net::LoadState AppCacheURLRequestJob::GetLoadState() const {
- if (!has_been_started())
- return net::LOAD_STATE_IDLE;
- if (!has_delivery_orders())
- return net::LOAD_STATE_WAITING_FOR_APPCACHE;
- if (delivery_type_ != APPCACHED_DELIVERY)
- return net::LOAD_STATE_IDLE;
- if (!info_.get())
- return net::LOAD_STATE_WAITING_FOR_APPCACHE;
- if (reader_.get() && reader_->IsReadPending())
- return net::LOAD_STATE_READING_RESPONSE;
- return net::LOAD_STATE_IDLE;
-}
-
-bool AppCacheURLRequestJob::GetMimeType(std::string* mime_type) const {
- if (!http_info())
- return false;
- return http_info()->headers->GetMimeType(mime_type);
-}
-
-bool AppCacheURLRequestJob::GetCharset(std::string* charset) {
- if (!http_info())
- return false;
- return http_info()->headers->GetCharset(charset);
-}
-
-void AppCacheURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
- if (!http_info())
- return;
- *info = *http_info();
-}
-
-int AppCacheURLRequestJob::GetResponseCode() const {
- if (!http_info())
- return -1;
- return http_info()->headers->response_code();
-}
-
-bool AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size,
- int *bytes_read) {
- DCHECK(is_delivering_appcache_response());
- DCHECK_NE(buf_size, 0);
- DCHECK(bytes_read);
- DCHECK(!reader_->IsReadPending());
- reader_->ReadData(
- buf, buf_size, base::Bind(&AppCacheURLRequestJob::OnReadComplete,
- base::Unretained(this)));
- SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0));
- return false;
-}
-
-void AppCacheURLRequestJob::SetExtraRequestHeaders(
- const net::HttpRequestHeaders& headers) {
- std::string value;
- std::vector<net::HttpByteRange> ranges;
- if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &value) ||
- !net::HttpUtil::ParseRangeHeader(value, &ranges)) {
- return;
- }
-
- // If multiple ranges are requested, we play dumb and
- // return the entire response with 200 OK.
- if (ranges.size() == 1U)
- range_requested_ = ranges[0];
-}
-
-} // namespace appcache

Powered by Google App Engine
This is Rietveld 408576698