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