net_error_helper.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/renderer/net/net_error_helper.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <string>
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/command_line.h"
10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/i18n/rtl.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/json/json_writer.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/metrics/histogram.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/utf_string_conversions.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/localized_error.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/net/net_error_info.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/render_messages.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/renderer/net/error_cache_load.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/content_renderer_client.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/renderer/render_frame.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/render_thread.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/render_view.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/renderer/resource_fetcher.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/renderer_resources.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message_macros.h"
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h"
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDataSource.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/webui/jstemplate_builder.h"
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::JSONWriter;
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatus;
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatusToString;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderFrame;
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderFrameObserver;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::RenderThread;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::kUnreachableWebDataURL;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Number of seconds to wait for the navigation correction service to return
53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// suggestions.  If it takes too long, just use the local error page.
54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstatic const int kNavigationCorrectionFetchTimeoutSec = 3;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NetErrorHelperCore::PageType GetLoadingPageType(const blink::WebFrame* frame) {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL url = frame->provisionalDataSource()->request().url();
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!url.is_valid() || url.spec() != kUnreachableWebDataURL)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NetErrorHelperCore::NON_ERROR_PAGE;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NetErrorHelperCore::ERROR_PAGE;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NetErrorHelperCore::FrameType GetFrameType(const blink::WebFrame* frame) {
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!frame->parent())
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NetErrorHelperCore::MAIN_FRAME;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NetErrorHelperCore::SUB_FRAME;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copied from localized_error.cc.
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// TODO(mmenke):  Share code?
71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool LocaleIsRTL() {
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(TOOLKIT_GTK)
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // base::i18n::IsRTL() uses the GTK text direction, which doesn't work within
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // the renderer sandbox.
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return base::i18n::ICUIsRTL();
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#else
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return base::i18n::IsRTL();
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NetErrorHelper::NetErrorHelper(RenderFrame* render_view)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : RenderFrameObserver(render_view),
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::RenderFrameObserverTracker<NetErrorHelper>(render_view),
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      core_(this) {
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderThread::Get()->AddObserver(this);
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool auto_reload_enabled =
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      command_line->HasSwitch(switches::kEnableOfflineAutoReload);
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  core_.set_auto_reload_enabled(auto_reload_enabled);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetErrorHelper::~NetErrorHelper() {
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderThread::Get()->RemoveObserver(this);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::DidStartProvisionalLoad() {
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = render_frame()->GetWebFrame();
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_.OnStartLoad(GetFrameType(frame), GetLoadingPageType(frame));
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::DidCommitProvisionalLoad(bool is_new_navigation) {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = render_frame()->GetWebFrame();
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_.OnCommitLoad(GetFrameType(frame));
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::DidFinishLoad() {
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = render_frame()->GetWebFrame();
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_.OnFinishLoad(GetFrameType(frame));
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::OnStop() {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_.OnStop();
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool NetErrorHelper::OnMessageReceived(const IPC::Message& message) {
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool handled = true;
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_BEGIN_MESSAGE_MAP(NetErrorHelper, message)
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_HANDLER(ChromeViewMsg_NetErrorInfo, OnNetErrorInfo)
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetNavigationCorrectionInfo,
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        OnSetNavigationCorrectionInfo);
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_UNHANDLED(handled = false)
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_END_MESSAGE_MAP()
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return handled;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetErrorHelper::NetworkStateChanged(bool enabled) {
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  core_.NetworkStateChanged(enabled);
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::GetErrorHTML(
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebFrame* frame,
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebURLError& error,
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool is_failed_post,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string* error_html) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_.GetErrorHTML(GetFrameType(frame), error, is_failed_post, error_html);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool NetErrorHelper::ShouldSuppressErrorPage(blink::WebFrame* frame,
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             const GURL& url) {
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return core_.ShouldSuppressErrorPage(GetFrameType(frame), url);
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::GenerateLocalizedErrorPage(
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const blink::WebURLError& error,
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bool is_failed_post,
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    scoped_ptr<LocalizedError::ErrorPageParams> params,
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    std::string* error_html) const {
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error_html->clear();
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int resource_id = IDR_NET_ERROR_HTML;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::StringPiece template_html(
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id));
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (template_html.empty()) {
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "unable to load template.";
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue error_strings;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LocalizedError::GetStrings(error.reason, error.domain.utf8(),
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               error.unreachableURL, is_failed_post,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               error.staleCopyInCache,
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               RenderThread::Get()->GetLocale(),
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               render_frame()->GetRenderView()->
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   GetAcceptLanguages(),
167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                               params.Pass(), &error_strings);
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // "t" is the id of the template's root node.
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error_html = webui::GetTemplatesHtml(template_html, &error_strings, "t");
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::LoadErrorPageInMainFrame(const std::string& html,
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              const GURL& failed_url) {
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!web_view)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = web_view->mainFrame();
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame->loadHTMLString(html, GURL(kUnreachableWebDataURL), failed_url, true);
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid NetErrorHelper::EnableStaleLoadBindings(const GURL& page_url) {
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ErrorCacheLoad::Install(render_frame(), page_url);
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::UpdateErrorPage(const blink::WebURLError& error,
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     bool is_failed_post) {
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue error_strings;
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  LocalizedError::GetStrings(error.reason,
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                             error.domain.utf8(),
19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                             error.unreachableURL,
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             is_failed_post,
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             error.staleCopyInCache,
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             RenderThread::Get()->GetLocale(),
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             render_frame()->GetRenderView()->
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 GetAcceptLanguages(),
197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             scoped_ptr<LocalizedError::ErrorPageParams>(),
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &error_strings);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string json;
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  JSONWriter::Write(&error_strings, &json);
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string js = "if (window.updateForDnsProbe) "
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   "updateForDnsProbe(" + json + ");";
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 js16;
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!base::UTF8ToUTF16(js.c_str(), js.length(), &js16)) {
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  render_frame()->ExecuteJavaScript(js16);
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::FetchNavigationCorrections(
215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& navigation_correction_url,
216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& navigation_correction_request_body) {
217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!correction_fetcher_.get());
218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!web_view)
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = web_view->mainFrame();
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_.reset(
225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      content::ResourceFetcher::Create(navigation_correction_url));
226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetMethod("POST");
227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetBody(navigation_correction_request_body);
228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetHeader("Content-Type", "application/json");
229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->Start(
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      frame, blink::WebURLRequest::TargetIsMainFrame,
231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Bind(&NetErrorHelper::OnNavigationCorrectionsFetched,
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Unretained(this)));
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
234a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetTimeout(
235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::TimeDelta::FromSeconds(kNavigationCorrectionFetchTimeoutSec));
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
238a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::CancelFetchNavigationCorrections() {
239a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_.reset();
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetErrorHelper::ReloadPage() {
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_frame()->GetWebFrame()->reload(false);
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::OnNetErrorInfo(int status_num) {
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(status_num >= 0 && status_num < chrome_common_net::DNS_PROBE_MAX);
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Received status " << DnsProbeStatusToString(status_num);
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  core_.OnNetErrorInfo(static_cast<DnsProbeStatus>(status_num));
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::OnSetNavigationCorrectionInfo(
255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& navigation_correction_url,
256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& language,
257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& country_code,
258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& api_key,
259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& search_url) {
260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  core_.OnSetNavigationCorrectionInfo(navigation_correction_url, language,
261a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                      country_code, api_key, search_url);
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
264a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::OnNavigationCorrectionsFetched(
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const blink::WebURLResponse& response,
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& data) {
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The fetcher may only be deleted after |data| is passed to |core_|.  Move
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // it to a temporary to prevent any potential re-entrancy issues.
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<content::ResourceFetcher> fetcher(
270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      correction_fetcher_.release());
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!response.isNull() && response.httpStatusCode() == 200) {
272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    core_.OnNavigationCorrectionsFetched(
273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        data, render_frame()->GetRenderView()->GetAcceptLanguages(),
274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        LocaleIsRTL());
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    core_.OnNavigationCorrectionsFetched(
277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        "", render_frame()->GetRenderView()->GetAcceptLanguages(),
278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        LocaleIsRTL());
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
281