// Copyright (c) 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.h"

#include <memory>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/json/json_writer.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
#include "chrome/renderer/ssl/ssl_certificate_error_page_controller.h"
#include "chrome/renderer/supervised_user/supervised_user_error_page_controller.h"
#include "components/error_page/common/error.h"
#include "components/error_page/common/error_page_params.h"
#include "components/error_page/common/localized_error.h"
#include "components/error_page/common/net_error_info.h"
#include "components/grit/components_resources.h"
#include "components/security_interstitials/core/common/interfaces/interstitial_commands.mojom.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/url_constants.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/resource_fetcher.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/net_errors.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_history_item.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
#include "url/gurl.h"

#if defined(OS_ANDROID)
#include "chrome/common/offline_page_auto_fetcher.mojom.h"
#endif

using base::JSONWriter;
using content::DocumentState;
using content::RenderFrame;
using content::RenderFrameObserver;
using content::RenderThread;
using content::kUnreachableWebDataURL;
using error_page::DnsProbeStatus;
using error_page::DnsProbeStatusToString;
using error_page::ErrorPageParams;
using error_page::LocalizedError;
using OfflineContentOnNetErrorFeatureState =
    LocalizedError::OfflineContentOnNetErrorFeatureState;

namespace {

// Number of seconds to wait for the navigation correction service to return
// suggestions.  If it takes too long, just use the local error page.
const int kNavigationCorrectionFetchTimeoutSec = 3;

NetErrorHelperCore::PageType GetLoadingPageType(
    blink::WebDocumentLoader* document_loader) {
  GURL url = document_loader->GetRequest().Url();
  if (!url.is_valid() || url.spec() != kUnreachableWebDataURL)
    return NetErrorHelperCore::NON_ERROR_PAGE;
  return NetErrorHelperCore::ERROR_PAGE;
}

NetErrorHelperCore::FrameType GetFrameType(RenderFrame* render_frame) {
  if (render_frame->IsMainFrame())
    return NetErrorHelperCore::MAIN_FRAME;
  return NetErrorHelperCore::SUB_FRAME;
}

#if defined(OS_ANDROID)
OfflineContentOnNetErrorFeatureState GetOfflineContentOnNetErrorFeatureState() {
  if (!base::FeatureList::IsEnabled(features::kNewNetErrorPageUI))
    return OfflineContentOnNetErrorFeatureState::kDisabled;
  const std::string alternate_ui_name = base::GetFieldTrialParamValueByFeature(
      features::kNewNetErrorPageUI,
      features::kNewNetErrorPageUIAlternateParameterName);
  if (alternate_ui_name == features::kNewNetErrorPageUIAlternateContentList) {
    return OfflineContentOnNetErrorFeatureState::kEnabledList;
  }
  return OfflineContentOnNetErrorFeatureState::kEnabledSummary;
}
#else   // OS_ANDROID
OfflineContentOnNetErrorFeatureState GetOfflineContentOnNetErrorFeatureState() {
  return OfflineContentOnNetErrorFeatureState::kDisabled;
}
#endif  // OS_ANDROID

#if defined(OS_ANDROID)
bool IsAutoFetchFeatureEnabled() {
  // This feature is incompatible with OfflineContentOnNetError, so don't allow
  // both.
  return GetOfflineContentOnNetErrorFeatureState() ==
             OfflineContentOnNetErrorFeatureState::kDisabled &&
         base::FeatureList::IsEnabled(features::kAutoFetchOnNetErrorPage);
}
#else   // OS_ANDROID
bool IsAutoFetchFeatureEnabled() {
  return false;
}
#endif  // OS_ANDROID

const net::NetworkTrafficAnnotationTag& GetNetworkTrafficAnnotationTag() {
  static const net::NetworkTrafficAnnotationTag network_traffic_annotation_tag =
      net::DefineNetworkTrafficAnnotation("net_error_helper", R"(
    semantics {
      sender: "NetErrorHelper"
      description:
        "Chrome asks Link Doctor service when a navigating page returns an "
        "error to investigate details about what is wrong."
      trigger:
        "When Chrome navigates to a page, and the page returns an error."
      data:
        "Failed page information including the URL will be sent to the service."
      destination: GOOGLE_OWNED_SERVICE
    }
    policy {
      cookies_allowed: NO
      setting:
        "You can enable or disable this feature via 'Use a web service to help "
        "resolve navigation errors' in Chrome's settings under Advanced. The "
        "feature is enabled by default."
      chrome_policy {
        AlternateErrorPagesEnabled {
          policy_options {mode: MANDATORY}
          AlternateErrorPagesEnabled: false
        }
      }
    })");
  return network_traffic_annotation_tag;
}

}  // namespace

NetErrorHelper::NetErrorHelper(RenderFrame* render_frame)
    : RenderFrameObserver(render_frame),
      content::RenderFrameObserverTracker<NetErrorHelper>(render_frame),
      weak_controller_delegate_factory_(this),
      weak_ssl_error_controller_delegate_factory_(this),
      weak_supervised_user_error_controller_delegate_factory_(this) {
  RenderThread::Get()->AddObserver(this);
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  bool auto_reload_enabled =
      command_line->HasSwitch(switches::kEnableOfflineAutoReload);
  bool auto_reload_visible_only =
      command_line->HasSwitch(switches::kEnableOfflineAutoReloadVisibleOnly);
  // TODO(mmenke): Consider only creating a NetErrorHelperCore for main frames.
  // subframes don't need any of the NetErrorHelperCore's extra logic.
  core_.reset(new NetErrorHelperCore(this,
                                     auto_reload_enabled,
                                     auto_reload_visible_only,
                                     !render_frame->IsHidden()));

  render_frame->GetAssociatedInterfaceRegistry()->AddInterface(
      base::Bind(&NetErrorHelper::OnNetworkDiagnosticsClientRequest,
                 base::Unretained(this)));
  render_frame->GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
      &NetErrorHelper::OnNavigationCorrectorRequest, base::Unretained(this)));
}

NetErrorHelper::~NetErrorHelper() {
  RenderThread::Get()->RemoveObserver(this);
}

void NetErrorHelper::ButtonPressed(NetErrorHelperCore::Button button) {
  core_->ExecuteButtonPress(button);
}

void NetErrorHelper::TrackClick(int tracking_id) {
  core_->TrackClick(tracking_id);
}

void NetErrorHelper::LaunchOfflineItem(const std::string& id,
                                       const std::string& name_space) {
  core_->LaunchOfflineItem(id, name_space);
}

void NetErrorHelper::LaunchDownloadsPage() {
  core_->LaunchDownloadsPage();
}

void NetErrorHelper::SavePageForLater() {
  core_->SavePageForLater();
}

void NetErrorHelper::CancelSavePage() {
  core_->CancelSavePage();
}

void NetErrorHelper::ListVisibilityChanged(bool is_visible) {
  core_->ListVisibilityChanged(is_visible);
}

content::RenderFrame* NetErrorHelper::GetRenderFrame() {
  return render_frame();
}

void NetErrorHelper::SendCommand(
    security_interstitials::SecurityInterstitialCommand command) {
  security_interstitials::mojom::InterstitialCommandsAssociatedPtr interface;
  render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(&interface);
  switch (command) {
    case security_interstitials::CMD_DONT_PROCEED: {
      interface->DontProceed();
      break;
    }
    case security_interstitials::CMD_PROCEED: {
      interface->Proceed();
      break;
    }
    case security_interstitials::CMD_SHOW_MORE_SECTION: {
      interface->ShowMoreSection();
      break;
    }
    case security_interstitials::CMD_OPEN_HELP_CENTER: {
      interface->OpenHelpCenter();
      break;
    }
    case security_interstitials::CMD_OPEN_DIAGNOSTIC: {
      interface->OpenDiagnostic();
      break;
    }
    case security_interstitials::CMD_RELOAD: {
      interface->Reload();
      break;
    }
    case security_interstitials::CMD_OPEN_DATE_SETTINGS: {
      interface->OpenDateSettings();
      break;
    }
    case security_interstitials::CMD_OPEN_LOGIN: {
      interface->OpenLogin();
      break;
    }
    case security_interstitials::CMD_DO_REPORT: {
      interface->DoReport();
      break;
    }
    case security_interstitials::CMD_DONT_REPORT: {
      interface->DontReport();
      break;
    }
    case security_interstitials::CMD_OPEN_REPORTING_PRIVACY: {
      interface->OpenReportingPrivacy();
      break;
    }
    case security_interstitials::CMD_OPEN_WHITEPAPER: {
      interface->OpenWhitepaper();
      break;
    }
    case security_interstitials::CMD_REPORT_PHISHING_ERROR: {
      interface->ReportPhishingError();
      break;
    }
    default: {
      // Other values in the enum are only used by tests so this
      // method should not be called with them.
      NOTREACHED();
    }
  }
}

void NetErrorHelper::GoBack() {
  if (supervised_user_interface_)
    supervised_user_interface_->GoBack();
}

void NetErrorHelper::RequestPermission(
    base::OnceCallback<void(bool)> callback) {
  if (supervised_user_interface_)
    supervised_user_interface_->RequestPermission(std::move(callback));
}

void NetErrorHelper::Feedback() {
  if (supervised_user_interface_)
    supervised_user_interface_->Feedback();
}

void NetErrorHelper::DidStartProvisionalLoad(
    blink::WebDocumentLoader* document_loader,
    bool is_content_initiated) {
  core_->OnStartLoad(GetFrameType(render_frame()),
                     GetLoadingPageType(document_loader));
}

void NetErrorHelper::DidCommitProvisionalLoad(bool is_same_document_navigation,
                                              ui::PageTransition transition) {
  // If this is a "same-document" navigation, it's not a real navigation.  There
  // wasn't a start event for it, either, so just ignore it.
  if (is_same_document_navigation)
    return;

  // Invalidate weak pointers from old error page controllers. If loading a new
  // error page, the controller has not yet been attached, so this won't affect
  // it.
  weak_controller_delegate_factory_.InvalidateWeakPtrs();
  weak_ssl_error_controller_delegate_factory_.InvalidateWeakPtrs();
  weak_supervised_user_error_controller_delegate_factory_.InvalidateWeakPtrs();

  core_->OnCommitLoad(GetFrameType(render_frame()),
                      render_frame()->GetWebFrame()->GetDocument().Url());
}

void NetErrorHelper::DidFinishLoad() {
  core_->OnFinishLoad(GetFrameType(render_frame()));
}

void NetErrorHelper::OnStop() {
  core_->OnStop();
}

void NetErrorHelper::WasShown() {
  core_->OnWasShown();
}

void NetErrorHelper::WasHidden() {
  core_->OnWasHidden();
}

void NetErrorHelper::OnDestruct() {
  delete this;
}

void NetErrorHelper::NetworkStateChanged(bool enabled) {
  core_->NetworkStateChanged(enabled);
}

void NetErrorHelper::PrepareErrorPage(const error_page::Error& error,
                                      bool is_failed_post,
                                      bool is_ignoring_cache,
                                      std::string* error_html) {
  core_->PrepareErrorPage(GetFrameType(render_frame()), error, is_failed_post,
                          is_ignoring_cache, error_html);
}

bool NetErrorHelper::ShouldSuppressErrorPage(const GURL& url) {
  return core_->ShouldSuppressErrorPage(GetFrameType(render_frame()), url);
}

chrome::mojom::NetworkDiagnostics*
NetErrorHelper::GetRemoteNetworkDiagnostics() {
  if (!remote_network_diagnostics_) {
    render_frame()->GetRemoteAssociatedInterfaces()
        ->GetInterface(&remote_network_diagnostics_);
  }
  return remote_network_diagnostics_.get();
}

chrome::mojom::NetworkEasterEgg* NetErrorHelper::GetRemoteNetworkEasterEgg() {
  if (!remote_network_easter_egg_) {
    render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
        &remote_network_easter_egg_);
  }
  return remote_network_easter_egg_.get();
}

void NetErrorHelper::GenerateLocalizedErrorPage(
    const error_page::Error& error,
    bool is_failed_post,
    bool can_show_network_diagnostics_dialog,
    std::unique_ptr<ErrorPageParams> params,
    bool* reload_button_shown,
    bool* show_saved_copy_button_shown,
    bool* show_cached_copy_button_shown,
    bool* download_button_shown,
    OfflineContentOnNetErrorFeatureState* offline_content_feature_state,
    bool* auto_fetch_allowed,
    std::string* error_html) const {
  error_html->clear();

  int resource_id = IDR_NET_ERROR_HTML;
  const base::StringPiece template_html(
      ui::ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id));
  if (template_html.empty()) {
    NOTREACHED() << "unable to load template.";
  } else {
    base::DictionaryValue error_strings;
    *offline_content_feature_state = GetOfflineContentOnNetErrorFeatureState();
    LocalizedError::GetStrings(
        error.reason(), error.domain(), error.url(), is_failed_post,
        error.stale_copy_in_cache(), can_show_network_diagnostics_dialog,
        ChromeRenderThreadObserver::is_incognito_process(),
        *offline_content_feature_state, IsAutoFetchFeatureEnabled(),
        RenderThread::Get()->GetLocale(), std::move(params), &error_strings);
    *reload_button_shown = error_strings.Get("reloadButton", nullptr);
    *show_saved_copy_button_shown =
        error_strings.Get("showSavedCopyButton", nullptr);
    *show_cached_copy_button_shown =
        error_strings.Get("cacheButton", nullptr);
    *download_button_shown =
        error_strings.Get("downloadButton", nullptr);
    if (!error_strings.Get("suggestedOfflineContentPresentationMode",
                           nullptr)) {
      *offline_content_feature_state =
          OfflineContentOnNetErrorFeatureState::kDisabled;
    }
    *auto_fetch_allowed = error_strings.FindKey("attemptAutoFetch") != nullptr;
    // "t" is the id of the template's root node.
    *error_html = webui::GetTemplatesHtml(template_html, &error_strings, "t");
  }
}

void NetErrorHelper::LoadErrorPage(const std::string& html,
                                   const GURL& failed_url) {
  render_frame()->LoadHTMLString(html, GURL(kUnreachableWebDataURL), "UTF-8",
                                 failed_url, true /* replace_current_item */);
}

void NetErrorHelper::EnablePageHelperFunctions(net::Error net_error) {
  if (net::IsCertificateError(net_error)) {
    SSLCertificateErrorPageController::Install(
        render_frame(),
        weak_ssl_error_controller_delegate_factory_.GetWeakPtr());
    return;
  }
  NetErrorPageController::Install(
      render_frame(), weak_controller_delegate_factory_.GetWeakPtr());

  render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
      &supervised_user_interface_);
  SupervisedUserErrorPageController::Install(
      render_frame(),
      weak_supervised_user_error_controller_delegate_factory_.GetWeakPtr());
}

void NetErrorHelper::UpdateErrorPage(const error_page::Error& error,
                                     bool is_failed_post,
                                     bool can_show_network_diagnostics_dialog) {
  base::DictionaryValue error_strings;
  LocalizedError::GetStrings(
      error.reason(), error.domain(), error.url(), is_failed_post,
      error.stale_copy_in_cache(), can_show_network_diagnostics_dialog,
      ChromeRenderThreadObserver::is_incognito_process(),
      GetOfflineContentOnNetErrorFeatureState(), IsAutoFetchFeatureEnabled(),
      RenderThread::Get()->GetLocale(), std::unique_ptr<ErrorPageParams>(),
      &error_strings);

  std::string json;
  JSONWriter::Write(error_strings, &json);

  std::string js = "if (window.updateForDnsProbe) "
                   "updateForDnsProbe(" + json + ");";
  base::string16 js16;
  if (!base::UTF8ToUTF16(js.c_str(), js.length(), &js16)) {
    NOTREACHED();
    return;
  }

  render_frame()->ExecuteJavaScript(js16);
}

void NetErrorHelper::InitializeErrorPageEasterEggHighScore(int high_score) {
  std::string js = base::StringPrintf(
      "if (window.initializeEasterEggHighScore) "
      "initializeEasterEggHighScore(%i);",
      high_score);
  base::string16 js16;
  if (!base::UTF8ToUTF16(js.c_str(), js.length(), &js16)) {
    NOTREACHED();
    return;
  }

  render_frame()->ExecuteJavaScript(js16);
}

void NetErrorHelper::RequestEasterEggHighScore() {
  GetRemoteNetworkEasterEgg()->GetHighScore(base::BindOnce(
      [](NetErrorHelper* helper, uint32_t high_score) {
        helper->core_->OnEasterEggHighScoreReceived(high_score);
      },
      base::Unretained(this)));
}

void NetErrorHelper::UpdateEasterEggHighScore(int high_score) {
  GetRemoteNetworkEasterEgg()->UpdateHighScore(high_score);
}

void NetErrorHelper::ResetEasterEggHighScore() {
  GetRemoteNetworkEasterEgg()->ResetHighScore();
}

void NetErrorHelper::FetchNavigationCorrections(
    const GURL& navigation_correction_url,
    const std::string& navigation_correction_request_body) {
  DCHECK(!correction_fetcher_.get());

  correction_fetcher_ =
      content::ResourceFetcher::Create(navigation_correction_url);
  correction_fetcher_->SetMethod("POST");
  correction_fetcher_->SetBody(navigation_correction_request_body);
  correction_fetcher_->SetHeader("Content-Type", "application/json");

  // Prevent CORB from triggering on this request by setting an Origin header.
  correction_fetcher_->SetHeader("Origin", "null");

  correction_fetcher_->Start(
      render_frame()->GetWebFrame(), blink::mojom::RequestContextType::INTERNAL,
      render_frame()->GetURLLoaderFactory(), GetNetworkTrafficAnnotationTag(),
      base::BindOnce(&NetErrorHelper::OnNavigationCorrectionsFetched,
                     base::Unretained(this)));

  correction_fetcher_->SetTimeout(
      base::TimeDelta::FromSeconds(kNavigationCorrectionFetchTimeoutSec));
}

void NetErrorHelper::CancelFetchNavigationCorrections() {
  correction_fetcher_.reset();
}

void NetErrorHelper::SendTrackingRequest(
    const GURL& tracking_url,
    const std::string& tracking_request_body) {
  // If there's already a pending tracking request, this will cancel it.
  tracking_fetcher_ = content::ResourceFetcher::Create(tracking_url);
  tracking_fetcher_->SetMethod("POST");
  tracking_fetcher_->SetBody(tracking_request_body);
  tracking_fetcher_->SetHeader("Content-Type", "application/json");

  tracking_fetcher_->Start(
      render_frame()->GetWebFrame(), blink::mojom::RequestContextType::INTERNAL,
      render_frame()->GetURLLoaderFactory(), GetNetworkTrafficAnnotationTag(),
      base::BindOnce(&NetErrorHelper::OnTrackingRequestComplete,
                     base::Unretained(this)));
}

void NetErrorHelper::ReloadPage(bool bypass_cache) {
  render_frame()->GetWebFrame()->StartReload(
      bypass_cache ? blink::WebFrameLoadType::kReloadBypassingCache
                   : blink::WebFrameLoadType::kReload);
}

void NetErrorHelper::LoadPageFromCache(const GURL& page_url) {
  blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame();
  DCHECK_NE("POST",
            web_frame->GetDocumentLoader()->GetRequest().HttpMethod().Ascii());

  blink::WebURLRequest request(page_url);
  request.SetCacheMode(blink::mojom::FetchCacheMode::kOnlyIfCached);
  request.SetRequestorOrigin(blink::WebSecurityOrigin::Create(page_url));
  web_frame->StartNavigation(request);
}

void NetErrorHelper::DiagnoseError(const GURL& page_url) {
  GetRemoteNetworkDiagnostics()->RunNetworkDiagnostics(page_url);
}

void NetErrorHelper::DownloadPageLater() {
#if defined(OS_ANDROID)
  render_frame()->Send(new ChromeViewHostMsg_DownloadPageLater(
      render_frame()->GetRoutingID()));
#endif  // defined(OS_ANDROID)
}

void NetErrorHelper::SetIsShowingDownloadButton(bool show) {
#if defined(OS_ANDROID)
  render_frame()->Send(
      new ChromeViewHostMsg_SetIsShowingDownloadButtonInErrorPage(
          render_frame()->GetRoutingID(), show));
#endif  // defined(OS_ANDROID)
}

void NetErrorHelper::OfflineContentAvailable(
    bool list_visible_by_prefs,
    const std::string& offline_content_json) {
#if defined(OS_ANDROID)
  if (!offline_content_json.empty()) {
    std::string isShownParam(list_visible_by_prefs ? "true" : "false");
    render_frame()->ExecuteJavaScript(base::UTF8ToUTF16(
        base::StrCat({"offlineContentAvailable(", isShownParam, ", ",
                      offline_content_json, ");"})));
  }
#endif
}

void NetErrorHelper::OfflineContentSummaryAvailable(
    const std::string& offline_content_summary_json) {
#if defined(OS_ANDROID)
  if (!offline_content_summary_json.empty()) {
    render_frame()->ExecuteJavaScript(
        base::UTF8ToUTF16(base::StrCat({"offlineContentSummaryAvailable(",
                                        offline_content_summary_json, ");"})));
  }
#endif  // defined(OS_ANDROID)
}

#if defined(OS_ANDROID)
void NetErrorHelper::SetAutoFetchState(
    chrome::mojom::OfflinePageAutoFetcherScheduleResult result) {
  const char* scheduled = "false";
  const char* can_schedule = "false";
  switch (result) {
    case chrome::mojom::OfflinePageAutoFetcherScheduleResult::kAlreadyScheduled:
    case chrome::mojom::OfflinePageAutoFetcherScheduleResult::kScheduled:
      scheduled = "true";
      can_schedule = "true";
      break;
    case chrome::mojom::OfflinePageAutoFetcherScheduleResult::kOtherError:
      break;
    case chrome::mojom::OfflinePageAutoFetcherScheduleResult::kNotEnoughQuota:
      can_schedule = "true";
      break;
  }
  render_frame()->ExecuteJavaScript(base::UTF8ToUTF16(base::StrCat(
      {"setAutoFetchState(", scheduled, ", ", can_schedule, ");"})));
}
#endif  // defined(OS_ANDROID)

void NetErrorHelper::DNSProbeStatus(int32_t status_num) {
  DCHECK(status_num >= 0 && status_num < error_page::DNS_PROBE_MAX);

  DVLOG(1) << "Received status " << DnsProbeStatusToString(status_num);

  core_->OnNetErrorInfo(static_cast<DnsProbeStatus>(status_num));
}

void NetErrorHelper::SetNavigationCorrectionInfo(
    const GURL& navigation_correction_url,
    const std::string& language,
    const std::string& country_code,
    const std::string& api_key,
    const GURL& search_url) {
  core_->OnSetNavigationCorrectionInfo(navigation_correction_url, language,
                                       country_code, api_key, search_url);
}

void NetErrorHelper::OnNavigationCorrectionsFetched(
    const blink::WebURLResponse& response,
    const std::string& data) {
  // The fetcher may only be deleted after |data| is passed to |core_|.  Move
  // it to a temporary to prevent any potential re-entrancy issues.
  std::unique_ptr<content::ResourceFetcher> fetcher(
      correction_fetcher_.release());
  bool success = (!response.IsNull() && response.HttpStatusCode() == 200);
  core_->OnNavigationCorrectionsFetched(success ? data : "",
                                        base::i18n::IsRTL());
}

void NetErrorHelper::OnTrackingRequestComplete(
    const blink::WebURLResponse& response,
    const std::string& data) {
  tracking_fetcher_.reset();
}

void NetErrorHelper::OnNetworkDiagnosticsClientRequest(
    chrome::mojom::NetworkDiagnosticsClientAssociatedRequest request) {
  network_diagnostics_client_bindings_.AddBinding(this, std::move(request));
}

void NetErrorHelper::OnNavigationCorrectorRequest(
    chrome::mojom::NavigationCorrectorAssociatedRequest request) {
  navigation_corrector_bindings_.AddBinding(this, std::move(request));
}

void NetErrorHelper::SetCanShowNetworkDiagnosticsDialog(bool can_show) {
  core_->OnSetCanShowNetworkDiagnosticsDialog(can_show);
}
