net_error_helper.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/renderer_resources.h"
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/renderer/net/net_error_page_controller.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/content_renderer_client.h"
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/renderer/document_state.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/renderer/render_frame.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/render_thread.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/renderer/render_view.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/renderer/resource_fetcher.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message_macros.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h"
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLResponse.h"
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDataSource.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebLocalFrame.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/webui/jstemplate_builder.h"
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::JSONWriter;
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatus;
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatusToString;
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using content::DocumentState;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderFrame;
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderFrameObserver;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::RenderThread;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::kUnreachableWebDataURL;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Number of seconds to wait for the navigation correction service to return
55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// suggestions.  If it takes too long, just use the local error page.
56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstatic const int kNavigationCorrectionFetchTimeoutSec = 3;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NetErrorHelperCore::PageType GetLoadingPageType(const blink::WebFrame* frame) {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL url = frame->provisionalDataSource()->request().url();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!url.is_valid() || url.spec() != kUnreachableWebDataURL)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NetErrorHelperCore::NON_ERROR_PAGE;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NetErrorHelperCore::ERROR_PAGE;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)NetErrorHelperCore::FrameType GetFrameType(const blink::WebFrame* frame) {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!frame->parent())
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NetErrorHelperCore::MAIN_FRAME;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return NetErrorHelperCore::SUB_FRAME;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)NetErrorHelper::NetErrorHelper(RenderFrame* render_frame)
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : RenderFrameObserver(render_frame),
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      content::RenderFrameObserverTracker<NetErrorHelper>(render_frame) {
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderThread::Get()->AddObserver(this);
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool auto_reload_enabled =
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      command_line->HasSwitch(switches::kEnableOfflineAutoReload);
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool auto_reload_visible_only =
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      command_line->HasSwitch(switches::kEnableOfflineAutoReloadVisibleOnly);
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_.reset(new NetErrorHelperCore(this,
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     auto_reload_enabled,
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     auto_reload_visible_only,
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     !render_frame->IsHidden()));
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetErrorHelper::~NetErrorHelper() {
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RenderThread::Get()->RemoveObserver(this);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid NetErrorHelper::ReloadButtonPressed() {
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->ExecuteButtonPress(NetErrorHelperCore::RELOAD_BUTTON);
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid NetErrorHelper::LoadStaleButtonPressed() {
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->ExecuteButtonPress(NetErrorHelperCore::LOAD_STALE_BUTTON);
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid NetErrorHelper::MoreButtonPressed() {
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->ExecuteButtonPress(NetErrorHelperCore::MORE_BUTTON);
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::DidStartProvisionalLoad() {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = render_frame()->GetWebFrame();
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnStartLoad(GetFrameType(frame), GetLoadingPageType(frame));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::DidCommitProvisionalLoad(bool is_new_navigation) {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = render_frame()->GetWebFrame();
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnCommitLoad(GetFrameType(frame), frame->document().url());
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::DidFinishLoad() {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = render_frame()->GetWebFrame();
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnFinishLoad(GetFrameType(frame));
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::OnStop() {
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnStop();
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void NetErrorHelper::WasShown() {
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnWasShown();
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void NetErrorHelper::WasHidden() {
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnWasHidden();
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool NetErrorHelper::OnMessageReceived(const IPC::Message& message) {
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool handled = true;
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_BEGIN_MESSAGE_MAP(NetErrorHelper, message)
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_HANDLER(ChromeViewMsg_NetErrorInfo, OnNetErrorInfo)
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetNavigationCorrectionInfo,
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                        OnSetNavigationCorrectionInfo);
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    IPC_MESSAGE_UNHANDLED(handled = false)
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  IPC_END_MESSAGE_MAP()
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return handled;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetErrorHelper::NetworkStateChanged(bool enabled) {
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->NetworkStateChanged(enabled);
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::GetErrorHTML(
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebFrame* frame,
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebURLError& error,
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool is_failed_post,
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string* error_html) {
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->GetErrorHTML(GetFrameType(frame), error, is_failed_post, error_html);
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool NetErrorHelper::ShouldSuppressErrorPage(blink::WebFrame* frame,
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             const GURL& url) {
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return core_->ShouldSuppressErrorPage(GetFrameType(frame), url);
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void NetErrorHelper::TrackClick(int tracking_id) {
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->TrackClick(tracking_id);
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::GenerateLocalizedErrorPage(
166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const blink::WebURLError& error,
167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bool is_failed_post,
168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    scoped_ptr<LocalizedError::ErrorPageParams> params,
1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool* reload_button_shown,
1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool* load_stale_button_shown,
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    std::string* error_html) const {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  error_html->clear();
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int resource_id = IDR_NET_ERROR_HTML;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::StringPiece template_html(
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id));
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (template_html.empty()) {
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED() << "unable to load template.";
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    CommandLine* command_line = CommandLine::ForCurrentProcess();
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool load_stale_cache_enabled =
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        command_line->HasSwitch(switches::kEnableOfflineLoadStaleCache);
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue error_strings;
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LocalizedError::GetStrings(error.reason, error.domain.utf8(),
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               error.unreachableURL, is_failed_post,
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               (load_stale_cache_enabled &&
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                error.staleCopyInCache && !is_failed_post),
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               RenderThread::Get()->GetLocale(),
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               render_frame()->GetRenderView()->
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   GetAcceptLanguages(),
192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                               params.Pass(), &error_strings);
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    *reload_button_shown = error_strings.Get("reloadButton", NULL);
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    *load_stale_button_shown = error_strings.Get("staleLoadButton", NULL);
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // "t" is the id of the template's root node.
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error_html = webui::GetTemplatesHtml(template_html, &error_strings, "t");
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::LoadErrorPageInMainFrame(const std::string& html,
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              const GURL& failed_url) {
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!web_view)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = web_view->mainFrame();
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame->loadHTMLString(html, GURL(kUnreachableWebDataURL), failed_url, true);
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid NetErrorHelper::EnablePageHelperFunctions() {
2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NetErrorPageController::Install(render_frame());
212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::UpdateErrorPage(const blink::WebURLError& error,
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     bool is_failed_post) {
216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    CommandLine* command_line = CommandLine::ForCurrentProcess();
217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool load_stale_cache_enabled =
218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        command_line->HasSwitch(switches::kEnableOfflineLoadStaleCache);
219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::DictionaryValue error_strings;
22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  LocalizedError::GetStrings(error.reason,
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                             error.domain.utf8(),
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                             error.unreachableURL,
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             is_failed_post,
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                             (load_stale_cache_enabled &&
226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              error.staleCopyInCache && !is_failed_post),
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             RenderThread::Get()->GetLocale(),
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             render_frame()->GetRenderView()->
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 GetAcceptLanguages(),
230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             scoped_ptr<LocalizedError::ErrorPageParams>(),
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             &error_strings);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string json;
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  JSONWriter::Write(&error_strings, &json);
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string js = "if (window.updateForDnsProbe) "
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   "updateForDnsProbe(" + json + ");";
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 js16;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!base::UTF8ToUTF16(js.c_str(), js.length(), &js16)) {
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  render_frame()->ExecuteJavaScript(js16);
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::FetchNavigationCorrections(
248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& navigation_correction_url,
249a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& navigation_correction_request_body) {
250a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!correction_fetcher_.get());
251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!web_view)
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  blink::WebFrame* frame = web_view->mainFrame();
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_.reset(
258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      content::ResourceFetcher::Create(navigation_correction_url));
259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetMethod("POST");
260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetBody(navigation_correction_request_body);
261a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetHeader("Content-Type", "application/json");
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
263a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->Start(
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame,
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      blink::WebURLRequest::RequestContextInternal,
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      blink::WebURLRequest::FrameTypeTopLevel,
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      content::ResourceFetcher::PLATFORM_LOADER,
268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Bind(&NetErrorHelper::OnNavigationCorrectionsFetched,
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Unretained(this)));
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
271a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_->SetTimeout(
272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::TimeDelta::FromSeconds(kNavigationCorrectionFetchTimeoutSec));
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::CancelFetchNavigationCorrections() {
276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  correction_fetcher_.reset();
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void NetErrorHelper::SendTrackingRequest(
280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GURL& tracking_url,
281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& tracking_request_body) {
282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!web_view)
284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  blink::WebFrame* frame = web_view->mainFrame();
286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // If there's already a pending tracking request, this will cancel it.
288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tracking_fetcher_.reset(content::ResourceFetcher::Create(tracking_url));
289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tracking_fetcher_->SetMethod("POST");
290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tracking_fetcher_->SetBody(tracking_request_body);
291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tracking_fetcher_->SetHeader("Content-Type", "application/json");
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
293010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tracking_fetcher_->Start(
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frame,
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      blink::WebURLRequest::RequestContextInternal,
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      blink::WebURLRequest::FrameTypeTopLevel,
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      content::ResourceFetcher::PLATFORM_LOADER,
298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      base::Bind(&NetErrorHelper::OnTrackingRequestComplete,
299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 base::Unretained(this)));
300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void NetErrorHelper::ReloadPage() {
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_frame()->GetWebFrame()->reload(false);
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid NetErrorHelper::LoadPageFromCache(const GURL& page_url) {
3070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebFrame* web_frame = render_frame()->GetWebFrame();
3080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(!EqualsASCII(web_frame->dataSource()->request().httpMethod(), "POST"));
3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebURLRequest request(page_url);
3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.setCachePolicy(blink::WebURLRequest::ReturnCacheDataDontLoad);
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  web_frame->loadRequest(request);
3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NetErrorHelper::OnNetErrorInfo(int status_num) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(status_num >= 0 && status_num < chrome_common_net::DNS_PROBE_MAX);
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Received status " << DnsProbeStatusToString(status_num);
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnNetErrorInfo(static_cast<DnsProbeStatus>(status_num));
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
324a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::OnSetNavigationCorrectionInfo(
325a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& navigation_correction_url,
326a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& language,
327a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& country_code,
328a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& api_key,
329a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& search_url) {
33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  core_->OnSetNavigationCorrectionInfo(navigation_correction_url, language,
331a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                      country_code, api_key, search_url);
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
334a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid NetErrorHelper::OnNavigationCorrectionsFetched(
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const blink::WebURLResponse& response,
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& data) {
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The fetcher may only be deleted after |data| is passed to |core_|.  Move
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // it to a temporary to prevent any potential re-entrancy issues.
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<content::ResourceFetcher> fetcher(
340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      correction_fetcher_.release());
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool success = (!response.isNull() && response.httpStatusCode() == 200);
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  core_->OnNavigationCorrectionsFetched(
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      success ? data : "",
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_frame()->GetRenderView()->GetAcceptLanguages(),
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::i18n::IsRTL());
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void NetErrorHelper::OnTrackingRequestComplete(
349010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const blink::WebURLResponse& response,
350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& data) {
351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  tracking_fetcher_.reset();
352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
353