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

Unified Diff: chrome/renderer/net/net_error_helper_core.cc

Issue 570253002: Componentize NetErrorHelperCore (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 2 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
« no previous file with comments | « chrome/renderer/net/net_error_helper_core.h ('k') | chrome/renderer/net/net_error_helper_core_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/net/net_error_helper_core.cc
diff --git a/chrome/renderer/net/net_error_helper_core.cc b/chrome/renderer/net/net_error_helper_core.cc
deleted file mode 100644
index 94196295869d1bc75ac517632ed30728a763b4e6..0000000000000000000000000000000000000000
--- a/chrome/renderer/net/net_error_helper_core.cc
+++ /dev/null
@@ -1,948 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/net/net_error_helper_core.h"
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/i18n/rtl.h"
-#include "base/json/json_reader.h"
-#include "base/json/json_value_converter.h"
-#include "base/json/json_writer.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/values.h"
-#include "chrome/common/localized_error.h"
-#include "chrome/grit/generated_resources.h"
-#include "content/public/common/url_constants.h"
-#include "net/base/escape.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-#include "third_party/WebKit/public/platform/WebURLError.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-namespace {
-
-struct CorrectionTypeToResourceTable {
- int resource_id;
- const char* correction_type;
-};
-
-const CorrectionTypeToResourceTable kCorrectionResourceTable[] = {
- {IDS_ERRORPAGES_SUGGESTION_VISIT_GOOGLE_CACHE, "cachedPage"},
- // "reloadPage" is has special handling.
- {IDS_ERRORPAGES_SUGGESTION_CORRECTED_URL, "urlCorrection"},
- {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "siteDomain"},
- {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "host"},
- {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "sitemap"},
- {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "pathParentFolder"},
- // "siteSearchQuery" is not yet supported.
- // TODO(mmenke): Figure out what format "siteSearchQuery" uses for its
- // suggestions.
- // "webSearchQuery" has special handling.
- {IDS_ERRORPAGES_SUGGESTION_ALTERNATE_URL, "contentOverlap"},
- {IDS_ERRORPAGES_SUGGESTION_CORRECTED_URL, "emphasizedUrlCorrection"},
-};
-
-struct NavigationCorrection {
- NavigationCorrection() : is_porn(false), is_soft_porn(false) {
- }
-
- static void RegisterJSONConverter(
- base::JSONValueConverter<NavigationCorrection>* converter) {
- converter->RegisterStringField("correctionType",
- &NavigationCorrection::correction_type);
- converter->RegisterStringField("urlCorrection",
- &NavigationCorrection::url_correction);
- converter->RegisterStringField("clickType",
- &NavigationCorrection::click_type);
- converter->RegisterStringField("clickData",
- &NavigationCorrection::click_data);
- converter->RegisterBoolField("isPorn", &NavigationCorrection::is_porn);
- converter->RegisterBoolField("isSoftPorn",
- &NavigationCorrection::is_soft_porn);
- }
-
- std::string correction_type;
- std::string url_correction;
- std::string click_type;
- std::string click_data;
- bool is_porn;
- bool is_soft_porn;
-};
-
-struct NavigationCorrectionResponse {
- std::string event_id;
- std::string fingerprint;
- ScopedVector<NavigationCorrection> corrections;
-
- static void RegisterJSONConverter(
- base::JSONValueConverter<NavigationCorrectionResponse>* converter) {
- converter->RegisterStringField("result.eventId",
- &NavigationCorrectionResponse::event_id);
- converter->RegisterStringField("result.fingerprint",
- &NavigationCorrectionResponse::fingerprint);
- converter->RegisterRepeatedMessage(
- "result.UrlCorrections",
- &NavigationCorrectionResponse::corrections);
- }
-};
-
-base::TimeDelta GetAutoReloadTime(size_t reload_count) {
- static const int kDelaysMs[] = {
- 0, 5000, 30000, 60000, 300000, 600000, 1800000
- };
- if (reload_count >= arraysize(kDelaysMs))
- reload_count = arraysize(kDelaysMs) - 1;
- return base::TimeDelta::FromMilliseconds(kDelaysMs[reload_count]);
-}
-
-// Returns whether |net_error| is a DNS-related error (and therefore whether
-// the tab helper should start a DNS probe after receiving it.)
-bool IsDnsError(const blink::WebURLError& error) {
- return error.domain.utf8() == net::kErrorDomain &&
- (error.reason == net::ERR_NAME_NOT_RESOLVED ||
- error.reason == net::ERR_NAME_RESOLUTION_FAILED);
-}
-
-GURL SanitizeURL(const GURL& url) {
- GURL::Replacements remove_params;
- remove_params.ClearUsername();
- remove_params.ClearPassword();
- remove_params.ClearQuery();
- remove_params.ClearRef();
- return url.ReplaceComponents(remove_params);
-}
-
-// Sanitizes and formats a URL for upload to the error correction service.
-std::string PrepareUrlForUpload(const GURL& url) {
- // TODO(yuusuke): Change to net::FormatUrl when Link Doctor becomes
- // unicode-capable.
- std::string spec_to_send = SanitizeURL(url).spec();
-
- // Notify navigation correction service of the url truncation by sending of
- // "?" at the end.
- if (url.has_query())
- spec_to_send.append("?");
- return spec_to_send;
-}
-
-// Given a WebURLError, returns true if the FixURL service should be used
-// for that error. Also sets |error_param| to the string that should be sent to
-// the FixURL service to identify the error type.
-bool ShouldUseFixUrlServiceForError(const blink::WebURLError& error,
- std::string* error_param) {
- error_param->clear();
-
- // Don't use the correction service for HTTPS (for privacy reasons).
- GURL unreachable_url(error.unreachableURL);
- if (GURL(unreachable_url).SchemeIsSecure())
- return false;
-
- std::string domain = error.domain.utf8();
- if (domain == "http" && error.reason == 404) {
- *error_param = "http404";
- return true;
- }
- if (IsDnsError(error)) {
- *error_param = "dnserror";
- return true;
- }
- if (domain == net::kErrorDomain &&
- (error.reason == net::ERR_CONNECTION_FAILED ||
- error.reason == net::ERR_CONNECTION_REFUSED ||
- error.reason == net::ERR_ADDRESS_UNREACHABLE ||
- error.reason == net::ERR_CONNECTION_TIMED_OUT)) {
- *error_param = "connectionFailure";
- return true;
- }
- return false;
-}
-
-// Creates a request body for use with the fixurl service. Sets parameters
-// shared by all types of requests to the service. |correction_params| must
-// contain the parameters specific to the actual request type.
-std::string CreateRequestBody(
- const std::string& method,
- const std::string& error_param,
- const NetErrorHelperCore::NavigationCorrectionParams& correction_params,
- scoped_ptr<base::DictionaryValue> params_dict) {
- // Set params common to all request types.
- params_dict->SetString("key", correction_params.api_key);
- params_dict->SetString("clientName", "chrome");
- params_dict->SetString("error", error_param);
-
- if (!correction_params.language.empty())
- params_dict->SetString("language", correction_params.language);
-
- if (!correction_params.country_code.empty())
- params_dict->SetString("originCountry", correction_params.country_code);
-
- base::DictionaryValue request_dict;
- request_dict.SetString("method", method);
- request_dict.SetString("apiVersion", "v1");
- request_dict.Set("params", params_dict.release());
-
- std::string request_body;
- bool success = base::JSONWriter::Write(&request_dict, &request_body);
- DCHECK(success);
- return request_body;
-}
-
-// If URL correction information should be retrieved remotely for a main frame
-// load that failed with |error|, returns true and sets
-// |correction_request_body| to be the body for the correction request.
-std::string CreateFixUrlRequestBody(
- const blink::WebURLError& error,
- const NetErrorHelperCore::NavigationCorrectionParams& correction_params) {
- std::string error_param;
- bool result = ShouldUseFixUrlServiceForError(error, &error_param);
- DCHECK(result);
-
- // TODO(mmenke): Investigate open sourcing the relevant protocol buffers and
- // using those directly instead.
- scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
- params->SetString("urlQuery", PrepareUrlForUpload(error.unreachableURL));
- return CreateRequestBody("linkdoctor.fixurl.fixurl", error_param,
- correction_params, params.Pass());
-}
-
-std::string CreateClickTrackingUrlRequestBody(
- const blink::WebURLError& error,
- const NetErrorHelperCore::NavigationCorrectionParams& correction_params,
- const NavigationCorrectionResponse& response,
- const NavigationCorrection& correction) {
- std::string error_param;
- bool result = ShouldUseFixUrlServiceForError(error, &error_param);
- DCHECK(result);
-
- scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-
- params->SetString("originalUrlQuery",
- PrepareUrlForUpload(error.unreachableURL));
-
- params->SetString("clickedUrlCorrection", correction.url_correction);
- params->SetString("clickType", correction.click_type);
- params->SetString("clickData", correction.click_data);
-
- params->SetString("eventId", response.event_id);
- params->SetString("fingerprint", response.fingerprint);
-
- return CreateRequestBody("linkdoctor.fixurl.clicktracking", error_param,
- correction_params, params.Pass());
-}
-
-base::string16 FormatURLForDisplay(const GURL& url, bool is_rtl,
- const std::string accept_languages) {
- // Translate punycode into UTF8, unescape UTF8 URLs.
- base::string16 url_for_display(net::FormatUrl(
- url, accept_languages, net::kFormatUrlOmitNothing,
- net::UnescapeRule::NORMAL, NULL, NULL, NULL));
- // URLs are always LTR.
- if (is_rtl)
- base::i18n::WrapStringWithLTRFormatting(&url_for_display);
- return url_for_display;
-}
-
-scoped_ptr<NavigationCorrectionResponse> ParseNavigationCorrectionResponse(
- const std::string raw_response) {
- // TODO(mmenke): Open source related protocol buffers and use them directly.
- scoped_ptr<base::Value> parsed(base::JSONReader::Read(raw_response));
- scoped_ptr<NavigationCorrectionResponse> response(
- new NavigationCorrectionResponse());
- base::JSONValueConverter<NavigationCorrectionResponse> converter;
- if (!parsed || !converter.Convert(*parsed, response.get()))
- response.reset();
- return response.Pass();
-}
-
-scoped_ptr<LocalizedError::ErrorPageParams> CreateErrorPageParams(
- const NavigationCorrectionResponse& response,
- const blink::WebURLError& error,
- const NetErrorHelperCore::NavigationCorrectionParams& correction_params,
- const std::string& accept_languages,
- bool is_rtl) {
- // Version of URL for display in suggestions. It has to be sanitized first
- // because any received suggestions will be relative to the sanitized URL.
- base::string16 original_url_for_display =
- FormatURLForDisplay(SanitizeURL(GURL(error.unreachableURL)), is_rtl,
- accept_languages);
-
- scoped_ptr<LocalizedError::ErrorPageParams> params(
- new LocalizedError::ErrorPageParams());
- params->override_suggestions.reset(new base::ListValue());
- scoped_ptr<base::ListValue> parsed_corrections(new base::ListValue());
- for (ScopedVector<NavigationCorrection>::const_iterator it =
- response.corrections.begin();
- it != response.corrections.end(); ++it) {
- // Doesn't seem like a good idea to show these.
- if ((*it)->is_porn || (*it)->is_soft_porn)
- continue;
-
- int tracking_id = it - response.corrections.begin();
-
- if ((*it)->correction_type == "reloadPage") {
- params->suggest_reload = true;
- params->reload_tracking_id = tracking_id;
- continue;
- }
-
- if ((*it)->correction_type == "webSearchQuery") {
- // If there are mutliple searches suggested, use the first suggestion.
- if (params->search_terms.empty()) {
- params->search_url = correction_params.search_url;
- params->search_terms = (*it)->url_correction;
- params->search_tracking_id = tracking_id;
- }
- continue;
- }
-
- // Allow reload page and web search query to be empty strings, but not
- // links.
- if ((*it)->url_correction.empty())
- continue;
- size_t correction_index;
- for (correction_index = 0;
- correction_index < arraysize(kCorrectionResourceTable);
- ++correction_index) {
- if ((*it)->correction_type !=
- kCorrectionResourceTable[correction_index].correction_type) {
- continue;
- }
- base::DictionaryValue* suggest = new base::DictionaryValue();
- suggest->SetString("header",
- l10n_util::GetStringUTF16(
- kCorrectionResourceTable[correction_index].resource_id));
- suggest->SetString("urlCorrection", (*it)->url_correction);
- suggest->SetString(
- "urlCorrectionForDisplay",
- FormatURLForDisplay(GURL((*it)->url_correction), is_rtl,
- accept_languages));
- suggest->SetString("originalUrlForDisplay", original_url_for_display);
- suggest->SetInteger("trackingId", tracking_id);
- params->override_suggestions->Append(suggest);
- break;
- }
- }
-
- if (params->override_suggestions->empty() && !params->search_url.is_valid())
- params.reset();
- return params.Pass();
-}
-
-void ReportAutoReloadSuccess(const blink::WebURLError& error, size_t count) {
- if (error.domain.utf8() != net::kErrorDomain)
- return;
- UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess",
- -error.reason,
- net::GetAllErrorCodesForUma());
- UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", count);
- if (count == 1) {
- UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess",
- -error.reason,
- net::GetAllErrorCodesForUma());
- }
-}
-
-void ReportAutoReloadFailure(const blink::WebURLError& error, size_t count) {
- if (error.domain.utf8() != net::kErrorDomain)
- return;
- UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop",
- -error.reason,
- net::GetAllErrorCodesForUma());
- UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", count);
-}
-
-} // namespace
-
-struct NetErrorHelperCore::ErrorPageInfo {
- ErrorPageInfo(blink::WebURLError error, bool was_failed_post)
- : error(error),
- was_failed_post(was_failed_post),
- needs_dns_updates(false),
- needs_load_navigation_corrections(false),
- reload_button_in_page(false),
- load_stale_button_in_page(false),
- is_finished_loading(false),
- auto_reload_triggered(false) {
- }
-
- // Information about the failed page load.
- blink::WebURLError error;
- bool was_failed_post;
-
- // Information about the status of the error page.
-
- // True if a page is a DNS error page and has not yet received a final DNS
- // probe status.
- bool needs_dns_updates;
-
- // True if a blank page was loaded, and navigation corrections need to be
- // loaded to generate the real error page.
- bool needs_load_navigation_corrections;
-
- // Navigation correction service paramers, which will be used in response to
- // certain types of network errors. They are all stored here in case they
- // change over the course of displaying the error page.
- scoped_ptr<NetErrorHelperCore::NavigationCorrectionParams>
- navigation_correction_params;
-
- scoped_ptr<NavigationCorrectionResponse> navigation_correction_response;
-
- // All the navigation corrections that have been clicked, for tracking
- // purposes.
- std::set<int> clicked_corrections;
-
- // Track if specific buttons are included in an error page, for statistics.
- bool reload_button_in_page;
- bool load_stale_button_in_page;
-
- // True if a page has completed loading, at which point it can receive
- // updates.
- bool is_finished_loading;
-
- // True if the auto-reload timer has fired and a reload is or has been in
- // flight.
- bool auto_reload_triggered;
-};
-
-NetErrorHelperCore::NavigationCorrectionParams::NavigationCorrectionParams() {
-}
-
-NetErrorHelperCore::NavigationCorrectionParams::~NavigationCorrectionParams() {
-}
-
-bool NetErrorHelperCore::IsReloadableError(
- const NetErrorHelperCore::ErrorPageInfo& info) {
- return info.error.domain.utf8() == net::kErrorDomain &&
- info.error.reason != net::ERR_ABORTED &&
- !info.was_failed_post;
-}
-
-NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate,
- bool auto_reload_enabled,
- bool auto_reload_visible_only,
- bool is_visible)
- : delegate_(delegate),
- last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE),
- auto_reload_enabled_(auto_reload_enabled),
- auto_reload_visible_only_(auto_reload_visible_only),
- auto_reload_timer_(new base::Timer(false, false)),
- auto_reload_paused_(false),
- uncommitted_load_started_(false),
- // TODO(ellyjones): Make online_ accurate at object creation.
- online_(true),
- visible_(is_visible),
- auto_reload_count_(0),
- navigation_from_button_(NO_BUTTON) {
-}
-
-NetErrorHelperCore::~NetErrorHelperCore() {
- if (committed_error_page_info_ &&
- committed_error_page_info_->auto_reload_triggered) {
- ReportAutoReloadFailure(committed_error_page_info_->error,
- auto_reload_count_);
- }
-}
-
-void NetErrorHelperCore::CancelPendingFetches() {
- // Cancel loading the alternate error page, and prevent any pending error page
- // load from starting a new error page load. Swapping in the error page when
- // it's finished loading could abort the navigation, otherwise.
- if (committed_error_page_info_)
- committed_error_page_info_->needs_load_navigation_corrections = false;
- if (pending_error_page_info_)
- pending_error_page_info_->needs_load_navigation_corrections = false;
- delegate_->CancelFetchNavigationCorrections();
- auto_reload_timer_->Stop();
- auto_reload_paused_ = false;
-}
-
-void NetErrorHelperCore::OnStop() {
- if (committed_error_page_info_ &&
- committed_error_page_info_->auto_reload_triggered) {
- ReportAutoReloadFailure(committed_error_page_info_->error,
- auto_reload_count_);
- }
- CancelPendingFetches();
- uncommitted_load_started_ = false;
- auto_reload_count_ = 0;
-}
-
-void NetErrorHelperCore::OnWasShown() {
- visible_ = true;
- if (!auto_reload_visible_only_)
- return;
- if (auto_reload_paused_)
- MaybeStartAutoReloadTimer();
-}
-
-void NetErrorHelperCore::OnWasHidden() {
- visible_ = false;
- if (!auto_reload_visible_only_)
- return;
- PauseAutoReloadTimer();
-}
-
-void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) {
- if (frame_type != MAIN_FRAME)
- return;
-
- uncommitted_load_started_ = true;
-
- // If there's no pending error page information associated with the page load,
- // or the new page is not an error page, then reset pending error page state.
- if (!pending_error_page_info_ || page_type != ERROR_PAGE)
- CancelPendingFetches();
-}
-
-void NetErrorHelperCore::OnCommitLoad(FrameType frame_type, const GURL& url) {
- if (frame_type != MAIN_FRAME)
- return;
-
- // uncommitted_load_started_ could already be false, since RenderFrameImpl
- // calls OnCommitLoad once for each in-page navigation (like a fragment
- // change) with no corresponding OnStartLoad.
- uncommitted_load_started_ = false;
-
- // Track if an error occurred due to a page button press.
- // This isn't perfect; if (for instance), the server is slow responding
- // to a request generated from the page reload button, and the user hits
- // the browser reload button, this code will still believe the
- // result is from the page reload button.
- if (committed_error_page_info_ && pending_error_page_info_ &&
- navigation_from_button_ != NO_BUTTON &&
- committed_error_page_info_->error.unreachableURL ==
- pending_error_page_info_->error.unreachableURL) {
- DCHECK(navigation_from_button_ == RELOAD_BUTTON ||
- navigation_from_button_ == LOAD_STALE_BUTTON);
- chrome_common_net::RecordEvent(
- navigation_from_button_ == RELOAD_BUTTON ?
- chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR :
- chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_ERROR);
- }
- navigation_from_button_ = NO_BUTTON;
-
- if (committed_error_page_info_ && !pending_error_page_info_ &&
- committed_error_page_info_->auto_reload_triggered) {
- const blink::WebURLError& error = committed_error_page_info_->error;
- const GURL& error_url = error.unreachableURL;
- if (url == error_url)
- ReportAutoReloadSuccess(error, auto_reload_count_);
- else if (url != GURL(content::kUnreachableWebDataURL))
- ReportAutoReloadFailure(error, auto_reload_count_);
- }
-
- committed_error_page_info_.reset(pending_error_page_info_.release());
-}
-
-void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
- if (frame_type != MAIN_FRAME)
- return;
-
- if (!committed_error_page_info_) {
- auto_reload_count_ = 0;
- return;
- }
-
- committed_error_page_info_->is_finished_loading = true;
-
- chrome_common_net::RecordEvent(chrome_common_net::NETWORK_ERROR_PAGE_SHOWN);
- if (committed_error_page_info_->reload_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_SHOWN);
- }
- if (committed_error_page_info_->load_stale_button_in_page) {
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_SHOWN);
- }
-
- delegate_->EnablePageHelperFunctions();
-
- if (committed_error_page_info_->needs_load_navigation_corrections) {
- // If there is another pending error page load, |fix_url| should have been
- // cleared.
- DCHECK(!pending_error_page_info_);
- DCHECK(!committed_error_page_info_->needs_dns_updates);
- delegate_->FetchNavigationCorrections(
- committed_error_page_info_->navigation_correction_params->url,
- CreateFixUrlRequestBody(
- committed_error_page_info_->error,
- *committed_error_page_info_->navigation_correction_params));
- } else if (auto_reload_enabled_ &&
- IsReloadableError(*committed_error_page_info_)) {
- MaybeStartAutoReloadTimer();
- }
-
- if (!committed_error_page_info_->needs_dns_updates ||
- last_probe_status_ == chrome_common_net::DNS_PROBE_POSSIBLE) {
- return;
- }
- DVLOG(1) << "Error page finished loading; sending saved status.";
- UpdateErrorPage();
-}
-
-void NetErrorHelperCore::GetErrorHTML(
- FrameType frame_type,
- const blink::WebURLError& error,
- bool is_failed_post,
- std::string* error_html) {
- if (frame_type == MAIN_FRAME) {
- // If navigation corrections were needed before, that should have been
- // cancelled earlier by starting a new page load (Which has now failed).
- DCHECK(!committed_error_page_info_ ||
- !committed_error_page_info_->needs_load_navigation_corrections);
-
- pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
- pending_error_page_info_->navigation_correction_params.reset(
- new NavigationCorrectionParams(navigation_correction_params_));
- GetErrorHtmlForMainFrame(pending_error_page_info_.get(), error_html);
- } else {
- // These values do not matter, as error pages in iframes hide the buttons.
- bool reload_button_in_page;
- bool load_stale_button_in_page;
-
- delegate_->GenerateLocalizedErrorPage(
- error, is_failed_post, scoped_ptr<LocalizedError::ErrorPageParams>(),
- &reload_button_in_page, &load_stale_button_in_page,
- error_html);
- }
-}
-
-void NetErrorHelperCore::OnNetErrorInfo(
- chrome_common_net::DnsProbeStatus status) {
- DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status);
-
- last_probe_status_ = status;
-
- if (!committed_error_page_info_ ||
- !committed_error_page_info_->needs_dns_updates ||
- !committed_error_page_info_->is_finished_loading) {
- return;
- }
-
- UpdateErrorPage();
-}
-
-void NetErrorHelperCore::OnSetNavigationCorrectionInfo(
- const GURL& navigation_correction_url,
- const std::string& language,
- const std::string& country_code,
- const std::string& api_key,
- const GURL& search_url) {
- navigation_correction_params_.url = navigation_correction_url;
- navigation_correction_params_.language = language;
- navigation_correction_params_.country_code = country_code;
- navigation_correction_params_.api_key = api_key;
- navigation_correction_params_.search_url = search_url;
-}
-
-void NetErrorHelperCore::GetErrorHtmlForMainFrame(
- ErrorPageInfo* pending_error_page_info,
- std::string* error_html) {
- std::string error_param;
- blink::WebURLError error = pending_error_page_info->error;
-
- if (pending_error_page_info->navigation_correction_params &&
- pending_error_page_info->navigation_correction_params->url.is_valid() &&
- ShouldUseFixUrlServiceForError(error, &error_param)) {
- pending_error_page_info->needs_load_navigation_corrections = true;
- return;
- }
-
- if (IsDnsError(pending_error_page_info->error)) {
- // The last probe status needs to be reset if this is a DNS error. This
- // means that if a DNS error page is committed but has not yet finished
- // loading, a DNS probe status scheduled to be sent to it may be thrown
- // out, but since the new error page should trigger a new DNS probe, it
- // will just get the results for the next page load.
- last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
- pending_error_page_info->needs_dns_updates = true;
- error = GetUpdatedError(error);
- }
-
- delegate_->GenerateLocalizedErrorPage(
- error, pending_error_page_info->was_failed_post,
- scoped_ptr<LocalizedError::ErrorPageParams>(),
- &pending_error_page_info->reload_button_in_page,
- &pending_error_page_info->load_stale_button_in_page,
- error_html);
-}
-
-void NetErrorHelperCore::UpdateErrorPage() {
- DCHECK(committed_error_page_info_->needs_dns_updates);
- DCHECK(committed_error_page_info_->is_finished_loading);
- DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, last_probe_status_);
-
- UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus",
- last_probe_status_,
- chrome_common_net::DNS_PROBE_MAX);
- // Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a
- // final status code. Once one is reached, the page does not need further
- // updates.
- if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED)
- committed_error_page_info_->needs_dns_updates = false;
-
- // There is no need to worry about the button display statistics here because
- // the presentation of the reload and load stale buttons can't be changed
- // by a DNS error update.
- delegate_->UpdateErrorPage(
- GetUpdatedError(committed_error_page_info_->error),
- committed_error_page_info_->was_failed_post);
-}
-
-void NetErrorHelperCore::OnNavigationCorrectionsFetched(
- const std::string& corrections,
- const std::string& accept_languages,
- bool is_rtl) {
- // Loading suggestions only starts when a blank error page finishes loading,
- // and is cancelled with a new load.
- DCHECK(!pending_error_page_info_);
- DCHECK(committed_error_page_info_->is_finished_loading);
- DCHECK(committed_error_page_info_->needs_load_navigation_corrections);
- DCHECK(committed_error_page_info_->navigation_correction_params);
-
- pending_error_page_info_.reset(
- new ErrorPageInfo(committed_error_page_info_->error,
- committed_error_page_info_->was_failed_post));
- pending_error_page_info_->navigation_correction_response =
- ParseNavigationCorrectionResponse(corrections);
-
- std::string error_html;
- scoped_ptr<LocalizedError::ErrorPageParams> params;
- if (pending_error_page_info_->navigation_correction_response) {
- // Copy navigation correction parameters used for the request, so tracking
- // requests can still be sent if the configuration changes.
- pending_error_page_info_->navigation_correction_params.reset(
- new NavigationCorrectionParams(
- *committed_error_page_info_->navigation_correction_params));
- params = CreateErrorPageParams(
- *pending_error_page_info_->navigation_correction_response,
- pending_error_page_info_->error,
- *pending_error_page_info_->navigation_correction_params,
- accept_languages, is_rtl);
- delegate_->GenerateLocalizedErrorPage(
- pending_error_page_info_->error,
- pending_error_page_info_->was_failed_post,
- params.Pass(),
- &pending_error_page_info_->reload_button_in_page,
- &pending_error_page_info_->load_stale_button_in_page,
- &error_html);
- } else {
- // Since |navigation_correction_params| in |pending_error_page_info_| is
- // NULL, this won't trigger another attempt to load corrections.
- GetErrorHtmlForMainFrame(pending_error_page_info_.get(), &error_html);
- }
-
- // TODO(mmenke): Once the new API is in place, look into replacing this
- // double page load by just updating the error page, like DNS
- // probes do.
- delegate_->LoadErrorPageInMainFrame(
- error_html,
- pending_error_page_info_->error.unreachableURL);
-}
-
-blink::WebURLError NetErrorHelperCore::GetUpdatedError(
- const blink::WebURLError& error) const {
- // If a probe didn't run or wasn't conclusive, restore the original error.
- if (last_probe_status_ == chrome_common_net::DNS_PROBE_NOT_RUN ||
- last_probe_status_ ==
- chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE) {
- return error;
- }
-
- blink::WebURLError updated_error;
- updated_error.domain = blink::WebString::fromUTF8(
- chrome_common_net::kDnsProbeErrorDomain);
- updated_error.reason = last_probe_status_;
- updated_error.unreachableURL = error.unreachableURL;
- updated_error.staleCopyInCache = error.staleCopyInCache;
-
- return updated_error;
-}
-
-void NetErrorHelperCore::Reload() {
- if (!committed_error_page_info_) {
- return;
- }
- delegate_->ReloadPage();
-}
-
-bool NetErrorHelperCore::MaybeStartAutoReloadTimer() {
- if (!committed_error_page_info_ ||
- !committed_error_page_info_->is_finished_loading ||
- pending_error_page_info_ ||
- uncommitted_load_started_) {
- return false;
- }
-
- StartAutoReloadTimer();
- return true;
-}
-
-void NetErrorHelperCore::StartAutoReloadTimer() {
- DCHECK(committed_error_page_info_);
- DCHECK(IsReloadableError(*committed_error_page_info_));
-
- committed_error_page_info_->auto_reload_triggered = true;
-
- if (!online_ || (!visible_ && auto_reload_visible_only_)) {
- auto_reload_paused_ = true;
- return;
- }
-
- auto_reload_paused_ = false;
- base::TimeDelta delay = GetAutoReloadTime(auto_reload_count_);
- auto_reload_timer_->Stop();
- auto_reload_timer_->Start(FROM_HERE, delay,
- base::Bind(&NetErrorHelperCore::AutoReloadTimerFired,
- base::Unretained(this)));
-}
-
-void NetErrorHelperCore::AutoReloadTimerFired() {
- auto_reload_count_++;
- Reload();
-}
-
-void NetErrorHelperCore::PauseAutoReloadTimer() {
- if (!auto_reload_timer_->IsRunning())
- return;
- DCHECK(committed_error_page_info_);
- DCHECK(!auto_reload_paused_);
- DCHECK(committed_error_page_info_->auto_reload_triggered);
- auto_reload_timer_->Stop();
- auto_reload_paused_ = true;
-}
-
-void NetErrorHelperCore::NetworkStateChanged(bool online) {
- bool was_online = online_;
- online_ = online;
- if (!was_online && online) {
- // Transitioning offline -> online
- if (auto_reload_paused_)
- MaybeStartAutoReloadTimer();
- } else if (was_online && !online) {
- // Transitioning online -> offline
- if (auto_reload_timer_->IsRunning())
- auto_reload_count_ = 0;
- PauseAutoReloadTimer();
- }
-}
-
-bool NetErrorHelperCore::ShouldSuppressErrorPage(FrameType frame_type,
- const GURL& url) {
- // Don't suppress child frame errors.
- if (frame_type != MAIN_FRAME)
- return false;
-
- if (!auto_reload_enabled_)
- return false;
-
- // If there's no committed error page, this error page wasn't from an auto
- // reload.
- if (!committed_error_page_info_)
- return false;
-
- // If the error page wasn't reloadable, display it.
- if (!IsReloadableError(*committed_error_page_info_))
- return false;
-
- // If |auto_reload_timer_| is still running or is paused, this error page
- // isn't from an auto reload.
- if (auto_reload_timer_->IsRunning() || auto_reload_paused_)
- return false;
-
- // If the error page was reloadable, and the timer isn't running or paused, an
- // auto-reload has already been triggered.
- DCHECK(committed_error_page_info_->auto_reload_triggered);
-
- GURL error_url = committed_error_page_info_->error.unreachableURL;
- // TODO(ellyjones): also plumb the error code down to CCRC and check that
- if (error_url != url)
- return false;
-
- // Suppressed an error-page load; the previous uncommitted load was the error
- // page load starting, so forget about it.
- uncommitted_load_started_ = false;
-
- // The first iteration of the timer is started by OnFinishLoad calling
- // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are
- // suppressed in this function, subsequent iterations of the timer have to be
- // started here.
- MaybeStartAutoReloadTimer();
- return true;
-}
-
-void NetErrorHelperCore::ExecuteButtonPress(Button button) {
- switch (button) {
- case RELOAD_BUTTON:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_CLICKED);
- navigation_from_button_ = RELOAD_BUTTON;
- Reload();
- return;
- case LOAD_STALE_BUTTON:
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_CLICKED);
- navigation_from_button_ = LOAD_STALE_BUTTON;
- delegate_->LoadPageFromCache(
- committed_error_page_info_->error.unreachableURL);
- return;
- case MORE_BUTTON:
- // Visual effects on page are handled in Javascript code.
- chrome_common_net::RecordEvent(
- chrome_common_net::NETWORK_ERROR_PAGE_MORE_BUTTON_CLICKED);
- return;
- case NO_BUTTON:
- NOTREACHED();
- return;
- }
-}
-
-void NetErrorHelperCore::TrackClick(int tracking_id) {
- // It's technically possible for |navigation_correction_params| to be NULL but
- // for |navigation_correction_response| not to be NULL, if the paramters
- // changed between loading the original error page and loading the error page
- if (!committed_error_page_info_ ||
- !committed_error_page_info_->navigation_correction_response) {
- return;
- }
-
- NavigationCorrectionResponse* response =
- committed_error_page_info_->navigation_correction_response.get();
-
- // |tracking_id| is less than 0 when the error page was not generated by the
- // navigation correction service. |tracking_id| should never be greater than
- // the array size, but best to be safe, since it contains data from a remote
- // site, though none of that data should make it into Javascript callbacks.
- if (tracking_id < 0 ||
- static_cast<size_t>(tracking_id) >= response->corrections.size()) {
- return;
- }
-
- // Only report a clicked link once.
- if (committed_error_page_info_->clicked_corrections.count(tracking_id))
- return;
-
- committed_error_page_info_->clicked_corrections.insert(tracking_id);
- std::string request_body = CreateClickTrackingUrlRequestBody(
- committed_error_page_info_->error,
- *committed_error_page_info_->navigation_correction_params,
- *response,
- *response->corrections[tracking_id]);
- delegate_->SendTrackingRequest(
- committed_error_page_info_->navigation_correction_params->url,
- request_body);
-}
-
« no previous file with comments | « chrome/renderer/net/net_error_helper_core.h ('k') | chrome/renderer/net/net_error_helper_core_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698