Index: webkit/browser/appcache/appcache_update_job.cc |
diff --git a/webkit/browser/appcache/appcache_update_job.cc b/webkit/browser/appcache/appcache_update_job.cc |
index 33a68b04a89f75b6506f6ebe61fce68d9dc89186..e968100f46e9b745c2d1e60c53a70540dc5c07ff 100644 |
--- a/webkit/browser/appcache/appcache_update_job.cc |
+++ b/webkit/browser/appcache/appcache_update_job.cc |
@@ -76,12 +76,12 @@ class HostNotifier { |
} |
} |
- void SendErrorNotifications(const std::string& error_message) { |
- DCHECK(!error_message.empty()); |
+ void SendErrorNotifications(const ErrorDetails& details) { |
+ DCHECK(!details.message.empty()); |
for (NotifyHostMap::iterator it = hosts_to_notify.begin(); |
it != hosts_to_notify.end(); ++it) { |
AppCacheFrontend* frontend = it->first; |
- frontend->OnErrorEventRaised(it->second, error_message); |
+ frontend->OnErrorEventRaised(it->second, details); |
} |
} |
@@ -112,8 +112,9 @@ AppCacheUpdateJob::URLFetcher::URLFetcher(const GURL& url, |
retry_503_attempts_(0), |
buffer_(new net::IOBuffer(kBufferSize)), |
request_(job->service_->request_context() |
- ->CreateRequest(url, net::DEFAULT_PRIORITY, this, NULL)), |
- result_(UPDATE_OK) {} |
+ ->CreateRequest(url, net::DEFAULT_PRIORITY, this, NULL)), |
+ result_(UPDATE_OK), |
+ redirect_response_code_(-1) {} |
AppCacheUpdateJob::URLFetcher::~URLFetcher() { |
} |
@@ -131,7 +132,6 @@ void AppCacheUpdateJob::URLFetcher::OnReceivedRedirect( |
net::URLRequest* request, const GURL& new_url, bool* defer_redirect) { |
DCHECK(request_ == request); |
// Redirect is not allowed by the update process. |
- job_->MadeProgress(); |
request->Cancel(); |
result_ = REDIRECT_ERROR; |
OnResponseCompleted(); |
@@ -158,6 +158,7 @@ void AppCacheUpdateJob::URLFetcher::OnResponseStarted( |
url_.GetOrigin() != job_->manifest_url_.GetOrigin()) { |
if (request->response_headers()-> |
HasHeaderValue("cache-control", "no-store")) { |
+ DCHECK_EQ(-1, redirect_response_code_); |
request->Cancel(); |
result_ = SERVER_ERROR; // Not the best match? |
OnResponseCompleted(); |
@@ -428,19 +429,17 @@ AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() { |
return writer; |
} |
-void AppCacheUpdateJob::HandleCacheFailure( |
- const std::string& error_message, |
- ResultType result, |
- const GURL& failed_resource_url) { |
jsbell
2014/03/27 19:30:43
Since I was already passing the failed resource UR
|
+void AppCacheUpdateJob::HandleCacheFailure(const ErrorDetails& error_details, |
+ ResultType result) { |
// 6.9.4 cache failure steps 2-8. |
DCHECK(internal_state_ != CACHE_FAILURE); |
- DCHECK(!error_message.empty()); |
+ DCHECK(!error_details.message.empty()); |
DCHECK(result != UPDATE_OK); |
internal_state_ = CACHE_FAILURE; |
- LogHistogramStats(result, failed_resource_url); |
+ LogHistogramStats(result, error_details.url); |
CancelAllUrlFetches(); |
- CancelAllMasterEntryFetches(error_message); |
- NotifyAllError(error_message); |
+ CancelAllMasterEntryFetches(error_details); |
+ NotifyAllError(error_details); |
DiscardInprogressCache(); |
internal_state_ = COMPLETED; |
DeleteSoon(); // To unwind the stack prior to deletion. |
@@ -501,20 +500,31 @@ void AppCacheUpdateJob::HandleManifestFetchCompleted( |
ContinueHandleManifestFetchCompleted(false); |
} else if ((response_code == 404 || response_code == 410) && |
update_type_ == UPGRADE_ATTEMPT) { |
- storage_->MakeGroupObsolete(group_, this); // async |
+ storage_->MakeGroupObsolete(group_, this, response_code); // async |
} else { |
const char* kFormatString = "Manifest fetch failed (%d) %s"; |
std::string message = FormatUrlErrorMessage( |
kFormatString, manifest_url_, fetcher->result(), response_code); |
- HandleCacheFailure(message, fetcher->result(), GURL()); |
+ HandleCacheFailure(ErrorDetails(message, |
+ appcache::MANIFEST_ERROR, |
+ manifest_url_, |
jsbell
2014/03/27 19:30:43
Here the manifest URL is passed through instead of
|
+ response_code, |
+ false /*is_cross_origin*/), |
+ fetcher->result()); |
} |
} |
void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, |
- bool success) { |
+ bool success, |
+ int response_code) { |
DCHECK(master_entry_fetches_.empty()); |
- CancelAllMasterEntryFetches("The cache has been made obsolete, " |
- "the manifest file returned 404 or 410"); |
+ CancelAllMasterEntryFetches(ErrorDetails( |
+ "The cache has been made obsolete, " |
+ "the manifest file returned 404 or 410", |
+ appcache::MANIFEST_ERROR, |
+ GURL(), |
+ response_code, |
+ false /*is_cross_origin*/)); |
if (success) { |
DCHECK(group->is_obsolete()); |
NotifyAllAssociatedHosts(OBSOLETE_EVENT); |
@@ -522,8 +532,12 @@ void AppCacheUpdateJob::OnGroupMadeObsolete(AppCacheGroup* group, |
MaybeCompleteUpdate(); |
} else { |
// Treat failure to mark group obsolete as a cache failure. |
- HandleCacheFailure("Failed to mark the cache as obsolete", |
- DB_ERROR, GURL()); |
+ HandleCacheFailure(ErrorDetails("Failed to mark the cache as obsolete", |
+ UNKNOWN_ERROR, |
+ GURL(), |
+ 0, |
+ false /*is_cross_origin*/), |
+ DB_ERROR); |
} |
} |
@@ -546,7 +560,10 @@ void AppCacheUpdateJob::ContinueHandleManifestFetchCompleted(bool changed) { |
const char* kFormatString = "Failed to parse manifest %s"; |
const std::string message = base::StringPrintf(kFormatString, |
manifest_url_.spec().c_str()); |
- HandleCacheFailure(message, MANIFEST_ERROR, GURL()); |
+ HandleCacheFailure( |
+ ErrorDetails( |
+ message, SIGNATURE_ERROR, GURL(), 0, false /*is_cross_origin*/), |
+ MANIFEST_ERROR); |
VLOG(1) << message; |
return; |
} |
@@ -585,7 +602,8 @@ void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { |
++url_fetches_completed_; |
int response_code = request->status().is_success() |
- ? request->GetResponseCode() : -1; |
+ ? request->GetResponseCode() |
+ : fetcher->canceled_response_code(); |
AppCacheEntry& entry = url_file_list_.find(url)->second; |
if (response_code / 100 == 2) { |
@@ -620,7 +638,29 @@ void AppCacheUpdateJob::HandleUrlFetchCompleted(URLFetcher* fetcher) { |
const char* kFormatString = "Resource fetch failed (%d) %s"; |
std::string message = FormatUrlErrorMessage( |
kFormatString, url, fetcher->result(), response_code); |
- HandleCacheFailure(message, fetcher->result(), url); |
+ ResultType result = fetcher->result(); |
+ bool is_cross_origin = url.GetOrigin() != manifest_url_.GetOrigin(); |
+ switch (result) { |
+ case DISKCACHE_ERROR: |
+ HandleCacheFailure( |
+ ErrorDetails( |
+ message, UNKNOWN_ERROR, GURL(), 0, is_cross_origin), |
jsbell
2014/03/27 19:30:43
Here an empty URL is passed through instead of the
|
+ result); |
+ break; |
+ case NETWORK_ERROR: |
+ HandleCacheFailure( |
+ ErrorDetails(message, RESOURCE_ERROR, url, 0, is_cross_origin), |
+ result); |
+ break; |
+ default: |
+ HandleCacheFailure(ErrorDetails(message, |
+ RESOURCE_ERROR, |
+ url, |
+ response_code, |
+ is_cross_origin), |
+ result); |
+ break; |
+ } |
return; |
} |
} else if (response_code == 404 || response_code == 410) { |
@@ -705,7 +745,12 @@ void AppCacheUpdateJob::HandleMasterEntryFetchCompleted( |
const char* kFormatString = "Manifest fetch failed (%d) %s"; |
std::string message = FormatUrlErrorMessage( |
kFormatString, request->url(), fetcher->result(), response_code); |
- host_notifier.SendErrorNotifications(message); |
+ host_notifier.SendErrorNotifications( |
+ ErrorDetails(message, |
+ appcache::MANIFEST_ERROR, |
+ request->url(), |
+ response_code, |
+ false /*is_cross_origin*/)); |
// In downloading case, update result is different if all master entries |
// failed vs. only some failing. |
@@ -716,7 +761,12 @@ void AppCacheUpdateJob::HandleMasterEntryFetchCompleted( |
// Section 6.9.4, step 22.3. |
if (update_type_ == CACHE_ATTEMPT && pending_master_entries_.empty()) { |
- HandleCacheFailure(message, fetcher->result(), GURL()); |
+ HandleCacheFailure(ErrorDetails(message, |
+ appcache::MANIFEST_ERROR, |
+ request->url(), |
jsbell
2014/03/27 19:30:43
Here the request URL is passed through instead of
|
+ response_code, |
+ false /*is_cross_origin*/), |
+ fetcher->result()); |
return; |
} |
} |
@@ -758,13 +808,22 @@ void AppCacheUpdateJob::HandleManifestRefetchCompleted( |
<< " response code: " << response_code; |
ScheduleUpdateRetry(kRerunDelayMs); |
if (response_code == 200) { |
- HandleCacheFailure( |
- "Manifest changed during update", MANIFEST_ERROR, GURL()); |
+ HandleCacheFailure(ErrorDetails("Manifest changed during update", |
+ CHANGED_ERROR, |
+ GURL(), |
+ 0, |
+ false /*is_cross_origin*/), |
+ MANIFEST_ERROR); |
} else { |
const char* kFormatString = "Manifest re-fetch failed (%d) %s"; |
std::string message = FormatUrlErrorMessage( |
kFormatString, manifest_url_, fetcher->result(), response_code); |
- HandleCacheFailure(message, fetcher->result(), GURL()); |
+ HandleCacheFailure(ErrorDetails(message, |
+ appcache::MANIFEST_ERROR, |
+ GURL(), |
+ response_code, |
+ false /*is_cross_origin*/), |
+ fetcher->result()); |
} |
} |
} |
@@ -779,8 +838,13 @@ void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) { |
base::Bind(&AppCacheUpdateJob::OnManifestDataWriteComplete, |
base::Unretained(this))); |
} else { |
- HandleCacheFailure("Failed to write the manifest headers to storage", |
- DISKCACHE_ERROR, GURL()); |
+ HandleCacheFailure( |
+ ErrorDetails("Failed to write the manifest headers to storage", |
+ UNKNOWN_ERROR, |
+ GURL(), |
+ 0, |
+ false /*is_cross_origin*/), |
+ DISKCACHE_ERROR); |
} |
} |
@@ -793,8 +857,13 @@ void AppCacheUpdateJob::OnManifestDataWriteComplete(int result) { |
duplicate_response_ids_.push_back(entry.response_id()); |
StoreGroupAndCache(); |
} else { |
- HandleCacheFailure("Failed to write the manifest data to storage", |
- DISKCACHE_ERROR, GURL()); |
+ HandleCacheFailure( |
+ ErrorDetails("Failed to write the manifest data to storage", |
+ UNKNOWN_ERROR, |
+ GURL(), |
+ 0, |
+ false /*is_cross_origin*/), |
+ DISKCACHE_ERROR); |
} |
} |
@@ -830,12 +899,16 @@ void AppCacheUpdateJob::OnGroupAndNewestCacheStored(AppCacheGroup* group, |
inprogress_cache_ = newest_cache; |
ResultType result = DB_ERROR; |
+ ErrorReason reason = UNKNOWN_ERROR; |
std::string message("Failed to commit new cache to storage"); |
if (would_exceed_quota) { |
message.append(", would exceed quota"); |
result = QUOTA_ERROR; |
+ reason = appcache::QUOTA_ERROR; |
} |
- HandleCacheFailure(message, result, GURL()); |
+ HandleCacheFailure( |
+ ErrorDetails(message, reason, GURL(), 0, false /*is_cross_origin*/), |
+ result); |
} |
} |
@@ -863,10 +936,10 @@ void AppCacheUpdateJob::NotifyAllFinalProgress() { |
NotifyAllProgress(GURL()); |
} |
-void AppCacheUpdateJob::NotifyAllError(const std::string& error_message) { |
+void AppCacheUpdateJob::NotifyAllError(const ErrorDetails& details) { |
HostNotifier host_notifier; |
AddAllAssociatedHostsToNotifier(&host_notifier); |
- host_notifier.SendErrorNotifications(error_message); |
+ host_notifier.SendErrorNotifications(details); |
} |
void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier( |
@@ -920,8 +993,13 @@ void AppCacheUpdateJob::CheckIfManifestChanged() { |
if (service_->storage() == storage_) { |
// Use a local variable because service_ is reset in HandleCacheFailure. |
AppCacheService* service = service_; |
- HandleCacheFailure("Manifest entry not found in existing cache", |
- DB_ERROR, GURL()); |
+ HandleCacheFailure( |
+ ErrorDetails("Manifest entry not found in existing cache", |
+ UNKNOWN_ERROR, |
+ GURL(), |
+ 0, |
+ false /*is_cross_origin*/), |
+ DB_ERROR); |
AppCacheHistograms::AddMissingManifestEntrySample(); |
service->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); |
} |
@@ -1162,7 +1240,7 @@ void AppCacheUpdateJob::FetchMasterEntries() { |
} |
void AppCacheUpdateJob::CancelAllMasterEntryFetches( |
- const std::string& error_message) { |
+ const ErrorDetails& error_details) { |
// For now, cancel all in-progress fetches for master entries and pretend |
// all master entries fetches have completed. |
// TODO(jennb): Delete this when update no longer fetches master entries |
@@ -1198,7 +1276,7 @@ void AppCacheUpdateJob::CancelAllMasterEntryFetches( |
master_entries_to_fetch_.erase(master_entries_to_fetch_.begin()); |
} |
- host_notifier.SendErrorNotifications(error_message); |
+ host_notifier.SendErrorNotifications(error_details); |
} |
bool AppCacheUpdateJob::MaybeLoadFromNewestCache(const GURL& url, |