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

Unified Diff: content/browser/appcache/appcache_update_job.cc

Issue 2978373002: Move the URLFetcher class used by the AppCacheUpdateJob class into its own file. (Closed)
Patch Set: Move forward declaration for URLFetcher outside the AppCacheUpdateJob class to fix compile failures. Created 3 years, 5 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: content/browser/appcache/appcache_update_job.cc
diff --git a/content/browser/appcache/appcache_update_job.cc b/content/browser/appcache/appcache_update_job.cc
index ec16a5a27f2b93063f5328dc850371a7c1ef7ec5..3f50460147dac43aa01461959fa4cce730c20a44 100644
--- a/content/browser/appcache/appcache_update_job.cc
+++ b/content/browser/appcache/appcache_update_job.cc
@@ -14,15 +14,12 @@
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/appcache/appcache_group.h"
#include "content/browser/appcache/appcache_histograms.h"
+#include "content/browser/appcache/appcache_update_url_fetcher.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
-#include "net/http/http_request_headers.h"
-#include "net/http/http_response_headers.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_request_context.h"
#include "url/origin.h"
namespace content {
@@ -31,7 +28,6 @@ namespace {
const int kBufferSize = 32768;
const size_t kMaxConcurrentUrlFetches = 2;
-const int kMax503Retries = 3;
std::string FormatUrlErrorMessage(
const char* format, const GURL& url,
@@ -70,36 +66,6 @@ bool IsEvictableError(AppCacheUpdateJob::ResultType result,
void EmptyCompletionCallback(int result) {}
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
- net::DefineNetworkTrafficAnnotation("appcache_update_job", R"(
- semantics {
- sender: "HTML5 AppCache System"
- description:
- "Web pages can include a link to a manifest file which lists "
- "resources to be cached for offline access. The AppCache system"
- "retrieves those resources in the background."
- trigger:
- "User visits a web page containing a <html manifest=manifestUrl> "
- "tag, or navigates to a document retrieved from an existing appcache "
- "and some resource should be updated."
- data: "None"
- destination: WEBSITE
- }
- policy {
- cookies_allowed: true
- cookies_store: "user"
- setting:
- "Users can control this feature via the 'Cookies' setting under "
- "'Privacy, Content settings'. If cookies are disabled for a single "
- "site, appcaches are disabled for the site only. If they are totally "
- "disabled, all appcache requests will be stopped."
- chrome_policy {
- DefaultCookiesSetting {
- policy_options {mode: MANDATORY}
- DefaultCookiesSetting: 2
- }
- }
- })");
} // namespace
// Helper class for collecting hosts per frontend when sending notifications
@@ -178,260 +144,6 @@ AppCacheUpdateJob::UrlToFetch::UrlToFetch(const UrlToFetch& other) = default;
AppCacheUpdateJob::UrlToFetch::~UrlToFetch() {
}
-// Helper class to fetch resources. Depending on the fetch type,
-// can either fetch to an in-memory string or write the response
-// data out to the disk cache.
-AppCacheUpdateJob::URLFetcher::URLFetcher(const GURL& url,
- FetchType fetch_type,
- AppCacheUpdateJob* job)
- : url_(url),
- job_(job),
- fetch_type_(fetch_type),
- retry_503_attempts_(0),
- buffer_(new net::IOBuffer(kBufferSize)),
- request_(
- job->service_->request_context()->CreateRequest(url,
- net::DEFAULT_PRIORITY,
- this,
- kTrafficAnnotation)),
- result_(UPDATE_OK),
- redirect_response_code_(-1) {}
-
-AppCacheUpdateJob::URLFetcher::~URLFetcher() {
- // To defend against URLRequest calling delegate methods during
- // destruction, we test for a !request_ in those methods.
- std::unique_ptr<net::URLRequest> temp = std::move(request_);
-}
-
-void AppCacheUpdateJob::URLFetcher::Start() {
- request_->set_first_party_for_cookies(job_->manifest_url_);
- request_->set_initiator(url::Origin(job_->manifest_url_));
- if (fetch_type_ == MANIFEST_FETCH && job_->doing_full_update_check_)
- request_->SetLoadFlags(request_->load_flags() | net::LOAD_BYPASS_CACHE);
- else if (existing_response_headers_.get())
- AddConditionalHeaders(existing_response_headers_.get());
- request_->Start();
-}
-
-void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect(
- net::URLRequest* request,
- const net::RedirectInfo& redirect_info,
- bool* defer_redirect) {
- if (!request_)
- return;
- DCHECK_EQ(request_.get(), request);
- // Redirect is not allowed by the update process.
- job_->MadeProgress();
- redirect_response_code_ = request->GetResponseCode();
- request->Cancel();
- result_ = REDIRECT_ERROR;
- OnResponseCompleted(net::ERR_ABORTED);
-}
-
-void AppCacheUpdateJob::URLFetcher::OnResponseStarted(net::URLRequest* request,
- int net_error) {
- if (!request_)
- return;
- DCHECK_EQ(request_.get(), request);
- DCHECK_NE(net::ERR_IO_PENDING, net_error);
-
- int response_code = -1;
- if (net_error == net::OK) {
- response_code = request->GetResponseCode();
- job_->MadeProgress();
- }
-
- if ((response_code / 100) != 2) {
- if (response_code > 0)
- result_ = SERVER_ERROR;
- else
- result_ = NETWORK_ERROR;
- OnResponseCompleted(net_error);
- return;
- }
-
- if (url_.SchemeIsCryptographic()) {
- // Do not cache content with cert errors.
- // Also, we willfully violate the HTML5 spec at this point in order
- // to support the appcaching of cross-origin HTTPS resources.
- // We've opted for a milder constraint and allow caching unless
- // the resource has a "no-store" header. A spec change has been
- // requested on the whatwg list.
- // See http://code.google.com/p/chromium/issues/detail?id=69594
- // TODO(michaeln): Consider doing this for cross-origin HTTP too.
- const net::HttpNetworkSession::Params* session_params =
- request->context()->GetNetworkSessionParams();
- bool ignore_cert_errors = session_params &&
- session_params->ignore_certificate_errors;
- if ((net::IsCertStatusError(request->ssl_info().cert_status) &&
- !ignore_cert_errors) ||
- (url_.GetOrigin() != job_->manifest_url_.GetOrigin() &&
- request->response_headers()->
- HasHeaderValue("cache-control", "no-store"))) {
- DCHECK_EQ(-1, redirect_response_code_);
- request->Cancel();
- result_ = SECURITY_ERROR;
- OnResponseCompleted(net::ERR_ABORTED);
- return;
- }
- }
-
- // Write response info to storage for URL fetches. Wait for async write
- // completion before reading any response data.
- if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) {
- response_writer_.reset(job_->CreateResponseWriter());
- scoped_refptr<HttpResponseInfoIOBuffer> io_buffer(
- new HttpResponseInfoIOBuffer(
- new net::HttpResponseInfo(request->response_info())));
- response_writer_->WriteInfo(
- io_buffer.get(),
- base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this)));
- } else {
- ReadResponseData();
- }
-}
-
-void AppCacheUpdateJob::URLFetcher::OnReadCompleted(
- net::URLRequest* request, int bytes_read) {
- if (!request_)
- return;
- DCHECK_NE(net::ERR_IO_PENDING, bytes_read);
- DCHECK_EQ(request_.get(), request);
- bool data_consumed = true;
- if (bytes_read > 0) {
- job_->MadeProgress();
- data_consumed = ConsumeResponseData(bytes_read);
- if (data_consumed) {
- while (true) {
- bytes_read = request->Read(buffer_.get(), kBufferSize);
- if (bytes_read <= 0)
- break;
- data_consumed = ConsumeResponseData(bytes_read);
- if (!data_consumed)
- break;
- }
- }
- }
-
- if (data_consumed && bytes_read != net::ERR_IO_PENDING) {
- DCHECK_EQ(UPDATE_OK, result_);
- OnResponseCompleted(bytes_read);
- }
-}
-
-void AppCacheUpdateJob::URLFetcher::AddConditionalHeaders(
- const net::HttpResponseHeaders* headers) {
- DCHECK(request_);
- DCHECK(headers);
- net::HttpRequestHeaders extra_headers;
-
- // Add If-Modified-Since header if response info has Last-Modified header.
- const std::string last_modified = "Last-Modified";
- std::string last_modified_value;
- headers->EnumerateHeader(nullptr, last_modified, &last_modified_value);
- if (!last_modified_value.empty()) {
- extra_headers.SetHeader(net::HttpRequestHeaders::kIfModifiedSince,
- last_modified_value);
- }
-
- // Add If-None-Match header if response info has ETag header.
- const std::string etag = "ETag";
- std::string etag_value;
- headers->EnumerateHeader(nullptr, etag, &etag_value);
- if (!etag_value.empty()) {
- extra_headers.SetHeader(net::HttpRequestHeaders::kIfNoneMatch,
- etag_value);
- }
- if (!extra_headers.IsEmpty())
- request_->SetExtraRequestHeaders(extra_headers);
-}
-
-void AppCacheUpdateJob::URLFetcher::OnWriteComplete(int result) {
- if (result < 0) {
- request_->Cancel();
- result_ = DISKCACHE_ERROR;
- OnResponseCompleted(net::ERR_ABORTED);
- return;
- }
- ReadResponseData();
-}
-
-void AppCacheUpdateJob::URLFetcher::ReadResponseData() {
- InternalUpdateState state = job_->internal_state_;
- if (state == CACHE_FAILURE || state == CANCELLED || state == COMPLETED)
- return;
- int bytes_read = request_->Read(buffer_.get(), kBufferSize);
- if (bytes_read != net::ERR_IO_PENDING)
- OnReadCompleted(request_.get(), bytes_read);
-}
-
-// Returns false if response data is processed asynchronously, in which
-// case ReadResponseData will be invoked when it is safe to continue
-// reading more response data from the request.
-bool AppCacheUpdateJob::URLFetcher::ConsumeResponseData(int bytes_read) {
- DCHECK_GT(bytes_read, 0);
- switch (fetch_type_) {
- case MANIFEST_FETCH:
- case MANIFEST_REFETCH:
- manifest_data_.append(buffer_->data(), bytes_read);
- break;
- case URL_FETCH:
- case MASTER_ENTRY_FETCH:
- DCHECK(response_writer_.get());
- response_writer_->WriteData(
- buffer_.get(),
- bytes_read,
- base::Bind(&URLFetcher::OnWriteComplete, base::Unretained(this)));
- return false; // wait for async write completion to continue reading
- default:
- NOTREACHED();
- }
- return true;
-}
-
-void AppCacheUpdateJob::URLFetcher::OnResponseCompleted(int net_error) {
- if (net_error == net::OK)
- job_->MadeProgress();
-
- // Retry for 503s where retry-after is 0.
- if (net_error == net::OK && request_->GetResponseCode() == 503 &&
- MaybeRetryRequest()) {
- return;
- }
-
- switch (fetch_type_) {
- case MANIFEST_FETCH:
- job_->HandleManifestFetchCompleted(this, net_error);
- break;
- case URL_FETCH:
- job_->HandleUrlFetchCompleted(this, net_error);
- break;
- case MASTER_ENTRY_FETCH:
- job_->HandleMasterEntryFetchCompleted(this, net_error);
- break;
- case MANIFEST_REFETCH:
- job_->HandleManifestRefetchCompleted(this, net_error);
- break;
- default:
- NOTREACHED();
- }
-
- delete this;
-}
-
-bool AppCacheUpdateJob::URLFetcher::MaybeRetryRequest() {
- if (retry_503_attempts_ >= kMax503Retries ||
- !request_->response_headers()->HasHeaderValue("retry-after", "0")) {
- return false;
- }
- ++retry_503_attempts_;
- result_ = UPDATE_OK;
- request_ = job_->service_->request_context()->CreateRequest(
- url_, net::DEFAULT_PRIORITY, this, kTrafficAnnotation);
- Start();
- return true;
-}
-
AppCacheUpdateJob::AppCacheUpdateJob(AppCacheServiceImpl* service,
AppCacheGroup* group)
: service_(service),
@@ -597,11 +309,11 @@ void AppCacheUpdateJob::HandleCacheFailure(
void AppCacheUpdateJob::FetchManifest(bool is_first_fetch) {
DCHECK(!manifest_fetcher_);
- manifest_fetcher_ = new URLFetcher(
- manifest_url_,
- is_first_fetch ? URLFetcher::MANIFEST_FETCH :
- URLFetcher::MANIFEST_REFETCH,
- this);
+ manifest_fetcher_ =
+ new URLFetcher(manifest_url_,
+ is_first_fetch ? URLFetcher::MANIFEST_FETCH
+ : URLFetcher::MANIFEST_REFETCH,
+ this, kBufferSize);
if (is_first_fetch) {
// Maybe load the cached headers to make a condiditional request.
@@ -1304,7 +1016,7 @@ void AppCacheUpdateJob::FetchUrls() {
// Continues asynchronously after data is loaded from newest cache.
} else {
URLFetcher* fetcher = new URLFetcher(
- url_to_fetch.url, URLFetcher::URL_FETCH, this);
+ url_to_fetch.url, URLFetcher::URL_FETCH, this, kBufferSize);
if (url_to_fetch.existing_response_info.get() &&
group_->newest_complete_cache()) {
AppCacheEntry* existing_entry =
@@ -1426,8 +1138,8 @@ void AppCacheUpdateJob::FetchMasterEntries() {
}
}
} else {
- URLFetcher* fetcher = new URLFetcher(
- url, URLFetcher::MASTER_ENTRY_FETCH, this);
+ URLFetcher* fetcher = new URLFetcher(url, URLFetcher::MASTER_ENTRY_FETCH,
+ this, kBufferSize);
fetcher->Start();
master_entry_fetches_.insert(PendingUrlFetches::value_type(url, fetcher));
}
« no previous file with comments | « content/browser/appcache/appcache_update_job.h ('k') | content/browser/appcache/appcache_update_url_fetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698