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 683b2452fb60b966f1def817cffdadebd10e378e..f22ff36abbedfe3a78bc9291a40b5d85fe8ddc45 100644 |
--- a/content/browser/frame_host/navigator_impl.cc |
+++ b/content/browser/frame_host/navigator_impl.cc |
@@ -12,13 +12,13 @@ |
#include "content/browser/frame_host/navigation_controller_impl.h" |
#include "content/browser/frame_host/navigation_entry_impl.h" |
#include "content/browser/frame_host/navigation_request.h" |
+#include "content/browser/frame_host/navigation_request_info.h" |
#include "content/browser/frame_host/navigator_delegate.h" |
#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/browser/webui/web_ui_controller_factory_registry.h" |
#include "content/browser/webui/web_ui_impl.h" |
-#include "content/common/frame_messages.h" |
#include "content/common/navigation_params.h" |
#include "content/common/view_messages.h" |
#include "content/public/browser/browser_context.h" |
@@ -34,6 +34,7 @@ |
#include "content/public/common/content_switches.h" |
#include "content/public/common/url_constants.h" |
#include "content/public/common/url_utils.h" |
+#include "net/base/load_flags.h" |
namespace content { |
@@ -65,6 +66,50 @@ FrameMsg_Navigate_Type::Value GetNavigationType( |
return FrameMsg_Navigate_Type::NORMAL; |
} |
+// PlzNavigate |
+// Returns the net load flags to use based on the navigation type. |
+// TODO(clamy): unify the code with what is happening on the renderer side. |
+int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) { |
+ int load_flags = net::LOAD_NORMAL; |
+ switch (navigation_type) { |
+ case FrameMsg_Navigate_Type::RELOAD: |
+ case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL: |
+ load_flags |= net::LOAD_VALIDATE_CACHE; |
+ break; |
+ case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE: |
+ load_flags |= net::LOAD_BYPASS_CACHE; |
+ break; |
+ case FrameMsg_Navigate_Type::RESTORE: |
+ load_flags |= net::LOAD_PREFERRING_CACHE; |
+ break; |
+ case FrameMsg_Navigate_Type::RESTORE_WITH_POST: |
+ load_flags |= net::LOAD_ONLY_FROM_CACHE; |
+ break; |
+ case FrameMsg_Navigate_Type::NORMAL: |
+ default: |
+ break; |
+ } |
+ return load_flags; |
+} |
+ |
+// PlzNavigate |
+// Generates a default FrameHostMsg_BeginNavigation_Params to be used when there |
+// is no live renderer. |
+FrameHostMsg_BeginNavigation_Params MakeDefaultBeginNavigation( |
+ const RequestNavigationParams& request_params, |
+ FrameMsg_Navigate_Type::Value navigation_type) { |
+ FrameHostMsg_BeginNavigation_Params begin_navigation_params; |
+ begin_navigation_params.method = request_params.is_post ? "POST" : "GET"; |
+ begin_navigation_params.load_flags = |
+ LoadFlagFromNavigationType(navigation_type); |
+ |
+ // TODO(clamy): Post data from the browser should be put in the request body. |
+ // Headers should be filled in as well. |
+ |
+ begin_navigation_params.has_user_gesture = false; |
+ return begin_navigation_params; |
+} |
+ |
RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { |
if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kSitePerProcess)) |
@@ -308,28 +353,13 @@ bool NavigatorImpl::NavigateToEntry( |
RenderFrameHostManager* manager = |
render_frame_host->frame_tree_node()->render_manager(); |
- // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. Instead |
- // the RenderFrameHostManager handles the navigation requests for that frame |
- // node. |
+ // PlzNavigate: the RenderFrameHosts are no longer asked to navigate. |
if (CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kEnableBrowserSideNavigation)) { |
- FrameMsg_Navigate_Type::Value navigation_type = |
- GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
- scoped_ptr<NavigationRequest> navigation_request(new NavigationRequest( |
- render_frame_host->frame_tree_node()->frame_tree_node_id(), |
- CommonNavigationParams(entry.GetURL(), |
- entry.GetReferrer(), |
- entry.GetTransitionType(), |
- navigation_type, |
- !entry.IsViewSourceMode()), |
- CommitNavigationParams(entry.GetPageState(), |
- entry.GetIsOverridingUserAgent(), |
- navigation_start))); |
- RequestNavigationParams request_params(entry.GetHasPostData(), |
- entry.extra_headers(), |
- entry.GetBrowserInitiatedPostData()); |
- return manager->RequestNavigation(navigation_request.Pass(), |
- request_params); |
+ return RequestNavigation(render_frame_host->frame_tree_node(), |
+ entry, |
+ reload_type, |
+ navigation_start); |
} |
RenderFrameHostImpl* dest_render_frame_host = manager->Navigate(entry); |
@@ -407,6 +437,15 @@ bool NavigatorImpl::NavigateToPendingEntry( |
void NavigatorImpl::DidNavigate( |
RenderFrameHostImpl* render_frame_host, |
const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) { |
+ // PlzNavigate |
+ // The navigation request has been committed so the browser process doesn't |
+ // need to care about it anymore. |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)) { |
+ navigation_request_map_.erase( |
+ render_frame_host->frame_tree_node()->frame_tree_node_id()); |
+ } |
+ |
FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params); |
FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree(); |
bool use_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch( |
@@ -639,16 +678,88 @@ void NavigatorImpl::RequestTransferURL( |
delegate_->RequestOpenURL(render_frame_host, params); |
} |
+// PlzNavigate |
+void NavigatorImpl::OnBeginNavigation( |
+ FrameTreeNode* frame_tree_node, |
+ const FrameHostMsg_BeginNavigation_Params& params, |
+ const CommonNavigationParams& common_params) { |
+ CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
+ DCHECK(frame_tree_node); |
+ |
+ // TODO(clamy): In case of a renderer initiated navigation create a new |
+ // NavigationRequest. |
+ NavigationRequestMap::iterator it = navigation_request_map_.find( |
+ frame_tree_node->frame_tree_node_id()); |
+ DCHECK(it != navigation_request_map_.end()); |
+ NavigationRequest* navigation_request = it->second.get(); |
carlosk
2014/10/01 18:31:09
In the case of a hijacked renderer process it coul
clamy
2014/10/01 22:30:46
Yes, but this is actually covered by the TODO abov
|
+ |
+ // Update the referrer with the one received from the renderer. |
+ navigation_request->common_params().referrer = common_params.referrer; |
+ |
+ scoped_ptr<NavigationRequestInfo> info(new NavigationRequestInfo(params)); |
+ |
+ info->first_party_for_cookies = |
+ frame_tree_node->IsMainFrame() |
+ ? navigation_request->common_params().url |
+ : frame_tree_node->frame_tree()->root()->current_url(); |
+ info->is_main_frame = frame_tree_node->IsMainFrame(); |
+ info->parent_is_main_frame = !frame_tree_node->parent() ? |
+ false : frame_tree_node->parent()->IsMainFrame(); |
+ |
+ // TODO(clamy): Inform the RenderFrameHostManager that a navigation is about |
+ // to begin, so that it can speculatively spawn a new renderer if needed. |
+ |
+ navigation_request->BeginNavigation(info.Pass(), params.request_body); |
+} |
+ |
+// PlzNavigate |
void NavigatorImpl::CommitNavigation( |
- RenderFrameHostImpl* render_frame_host, |
- const GURL& stream_url, |
- const CommonNavigationParams& common_params, |
- const CommitNavigationParams& commit_params) { |
- CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host, |
- common_params.url); |
- render_frame_host->CommitNavigation(stream_url, common_params, commit_params); |
+ FrameTreeNode* frame_tree_node, |
+ const NavigationBeforeCommitInfo& info) { |
+ CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
+ NavigationRequestMap::iterator it = navigation_request_map_.find( |
+ frame_tree_node->frame_tree_node_id()); |
+ DCHECK(it != navigation_request_map_.end()); |
+ NavigationRequest* navigation_request = it->second.get(); |
+ |
+ // Ignores navigation commits if the request ID doesn't match the current |
+ // active request. |
+ if (navigation_request->navigation_request_id() != |
+ info.navigation_request_id) { |
+ return; |
+ } |
+ |
+ // Update the navigation url. |
+ navigation_request->common_params().url = info.navigation_url; |
+ |
+ // Select an appropriate renderer to commit the navigation. |
+ RenderFrameHostImpl* render_frame_host = |
+ frame_tree_node->render_manager()->GetFrameHostForNavigation( |
+ info.navigation_url, navigation_request->common_params().transition); |
+ CheckWebUIRendererDoesNotDisplayNormalURL( |
+ render_frame_host, navigation_request->common_params().url); |
+ |
+ render_frame_host->CommitNavigation(info.stream_url, |
+ navigation_request->common_params(), |
+ navigation_request->commit_params()); |
+} |
+ |
+// PlzNavigate |
+void NavigatorImpl::CancelNavigation(FrameTreeNode* frame_tree_node) { |
+ CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
+ NavigationRequestMap::iterator it = navigation_request_map_.find( |
+ frame_tree_node->frame_tree_node_id()); |
+ if (it == navigation_request_map_.end()) |
+ return; |
+ it->second->CancelNavigation(); |
+ navigation_request_map_.erase(frame_tree_node->frame_tree_node_id()); |
} |
+NavigatorImpl::~NavigatorImpl() {} |
+ |
void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL( |
RenderFrameHostImpl* render_frame_host, |
const GURL& url) { |
@@ -665,4 +776,56 @@ void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL( |
} |
} |
+// PlzNavigate |
+bool NavigatorImpl::RequestNavigation( |
+ FrameTreeNode* frame_tree_node, |
+ const NavigationEntryImpl& entry, |
+ NavigationController::ReloadType reload_type, |
+ base::TimeTicks navigation_start) { |
+ CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kEnableBrowserSideNavigation)); |
+ DCHECK(frame_tree_node); |
+ int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
+ FrameMsg_Navigate_Type::Value navigation_type = |
+ GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
+ linked_ptr<NavigationRequest> navigation_request(new NavigationRequest( |
+ frame_tree_node_id, |
+ CommonNavigationParams(entry.GetURL(), |
+ entry.GetReferrer(), |
+ entry.GetTransitionType(), |
+ navigation_type, |
+ !entry.IsViewSourceMode()), |
+ CommitNavigationParams(entry.GetPageState(), |
+ entry.GetIsOverridingUserAgent(), |
+ navigation_start))); |
+ RequestNavigationParams request_params(entry.GetHasPostData(), |
+ entry.extra_headers(), |
+ entry.GetBrowserInitiatedPostData()); |
+ // TODO(clamy): Check if navigations are blocked and if so store the |
+ // parameters. |
+ |
+ // If there is an ongoing request it must be canceled. |
+ NavigationRequestMap::iterator it = navigation_request_map_.find( |
+ frame_tree_node_id); |
+ if (it != navigation_request_map_.end()) |
+ it->second->CancelNavigation(); |
nasko
2014/10/01 15:59:49
Shouldn't we also erase the element from the map?
clamy
2014/10/01 17:10:43
We are replacing it just afterwards so it should b
nasko
2014/10/01 18:20:18
AFAIU, insert will not overwrite existing entries.
clamy
2014/10/01 22:30:46
Indeed it does not. But I am now using ScopedPtrHa
nasko
2014/10/02 00:09:39
Acknowledged.
|
+ |
+ navigation_request_map_.insert( |
+ std::pair<int64, linked_ptr<NavigationRequest> >( |
+ frame_tree_node_id, navigation_request)); |
carlosk
2014/10/01 18:31:10
I was also looking into this matter of the entry a
|
+ |
+ if (frame_tree_node->current_frame_host()->IsRenderFrameLive()) { |
+ // TODO(clamy): send a RequestNavigation IPC. |
+ return true; |
+ } |
+ |
+ // The navigation request is sent directly to the IO thread. |
+ OnBeginNavigation( |
+ frame_tree_node, |
+ MakeDefaultBeginNavigation( |
+ request_params, navigation_request->common_params().navigation_type), |
+ navigation_request->common_params()); |
+ return true; |
+} |
+ |
} // namespace content |