| Index: content/browser/frame_host/navigator_impl.cc
|
| diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
|
| index 362f64cb03683179b02b3f5736da25e606c63d21..7adfe79445ace2bafe3760864f94fc0b1443dd3f 100644
|
| --- a/content/browser/frame_host/navigator_impl.cc
|
| +++ b/content/browser/frame_host/navigator_impl.cc
|
| @@ -5,6 +5,7 @@
|
| #include "content/browser/frame_host/navigator_impl.h"
|
|
|
| #include "base/command_line.h"
|
| +#include "content/browser/frame_host/frame_tree.h"
|
| #include "content/browser/frame_host/frame_tree_node.h"
|
| #include "content/browser/frame_host/navigation_controller_impl.h"
|
| #include "content/browser/frame_host/navigation_entry_impl.h"
|
| @@ -12,6 +13,7 @@
|
| #include "content/browser/frame_host/render_frame_host_impl.h"
|
| #include "content/browser/renderer_host/render_view_host_impl.h"
|
| #include "content/browser/site_instance_impl.h"
|
| +#include "content/common/frame_messages.h"
|
| #include "content/public/browser/browser_context.h"
|
| #include "content/public/browser/invalidate_type.h"
|
| #include "content/public/browser/navigation_controller.h"
|
| @@ -91,4 +93,65 @@ void NavigatorImpl::DidStartProvisionalLoad(
|
| }
|
| }
|
|
|
| +
|
| +void NavigatorImpl::DidFailProvisionalLoadWithError(
|
| + RenderFrameHostImpl* render_frame_host,
|
| + const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
|
| + VLOG(1) << "Failed Provisional Load: " << params.url.possibly_invalid_spec()
|
| + << ", error_code: " << params.error_code
|
| + << ", error_description: " << params.error_description
|
| + << ", is_main_frame: " << params.is_main_frame
|
| + << ", showing_repost_interstitial: " <<
|
| + params.showing_repost_interstitial
|
| + << ", frame_id: " << params.frame_id;
|
| + GURL validated_url(params.url);
|
| + RenderProcessHost* render_process_host = render_frame_host->GetProcess();
|
| + render_process_host->FilterURL(false, &validated_url);
|
| +
|
| + if (net::ERR_ABORTED == params.error_code) {
|
| + // EVIL HACK ALERT! Ignore failed loads when we're showing interstitials.
|
| + // This means that the interstitial won't be torn down properly, which is
|
| + // bad. But if we have an interstitial, go back to another tab type, and
|
| + // then load the same interstitial again, we could end up getting the first
|
| + // interstitial's "failed" message (as a result of the cancel) when we're on
|
| + // the second one. We can't tell this apart, so we think we're tearing down
|
| + // the current page which will cause a crash later on.
|
| + //
|
| + // http://code.google.com/p/chromium/issues/detail?id=2855
|
| + // Because this will not tear down the interstitial properly, if "back" is
|
| + // back to another tab type, the interstitial will still be somewhat alive
|
| + // in the previous tab type. If you navigate somewhere that activates the
|
| + // tab with the interstitial again, you'll see a flash before the new load
|
| + // commits of the interstitial page.
|
| + FrameTreeNode* root =
|
| + render_frame_host->frame_tree_node()->frame_tree()->root();
|
| + if (root->render_manager()->interstitial_page() != NULL) {
|
| + LOG(WARNING) << "Discarding message during interstitial.";
|
| + return;
|
| + }
|
| +
|
| + // We used to cancel the pending renderer here for cross-site downloads.
|
| + // However, it's not safe to do that because the download logic repeatedly
|
| + // looks for this WebContents based on a render ID. Instead, we just
|
| + // leave the pending renderer around until the next navigation event
|
| + // (Navigate, DidNavigate, etc), which will clean it up properly.
|
| + //
|
| + // TODO(creis): Find a way to cancel any pending RFH here.
|
| + }
|
| +
|
| + // Do not usually clear the pending entry if one exists, so that the user's
|
| + // typed URL is not lost when a navigation fails or is aborted. However, in
|
| + // cases that we don't show the pending entry (e.g., renderer-initiated
|
| + // navigations in an existing tab), we don't keep it around. That prevents
|
| + // spoofs on in-page navigations that don't go through
|
| + // DidStartProvisionalLoadForFrame.
|
| + // In general, we allow the view to clear the pending entry and typed URL if
|
| + // the user requests (e.g., hitting Escape with focus in the address bar).
|
| + // Note: don't touch the transient entry, since an interstitial may exist.
|
| + if (controller_->GetPendingEntry() != controller_->GetVisibleEntry())
|
| + controller_->DiscardPendingEntry();
|
| +
|
| + delegate_->DidFailProvisionalLoadWithError(render_frame_host, params);
|
| +}
|
| +
|
| } // namespace content
|
|
|