OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/frame_host/navigator_impl.h" | 5 #include "content/browser/frame_host/navigator_impl.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/browser/frame_host/frame_tree.h" | 10 #include "content/browser/frame_host/frame_tree.h" |
11 #include "content/browser/frame_host/frame_tree_node.h" | 11 #include "content/browser/frame_host/frame_tree_node.h" |
12 #include "content/browser/frame_host/navigation_controller_impl.h" | 12 #include "content/browser/frame_host/navigation_controller_impl.h" |
13 #include "content/browser/frame_host/navigation_entry_impl.h" | 13 #include "content/browser/frame_host/navigation_entry_impl.h" |
14 #include "content/browser/frame_host/navigation_request.h" | 14 #include "content/browser/frame_host/navigation_request.h" |
15 #include "content/browser/frame_host/navigation_request_info.h" | 15 #include "content/browser/frame_host/navigation_request_info.h" |
16 #include "content/browser/frame_host/navigator_delegate.h" | 16 #include "content/browser/frame_host/navigator_delegate.h" |
17 #include "content/browser/frame_host/render_frame_host_impl.h" | 17 #include "content/browser/frame_host/render_frame_host_impl.h" |
18 #include "content/browser/renderer_host/render_view_host_impl.h" | 18 #include "content/browser/renderer_host/render_view_host_impl.h" |
19 #include "content/browser/site_instance_impl.h" | 19 #include "content/browser/site_instance_impl.h" |
20 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 20 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
21 #include "content/browser/webui/web_ui_impl.h" | 21 #include "content/browser/webui/web_ui_impl.h" |
22 #include "content/common/frame_messages.h" | |
22 #include "content/common/navigation_params.h" | 23 #include "content/common/navigation_params.h" |
23 #include "content/common/view_messages.h" | 24 #include "content/common/view_messages.h" |
24 #include "content/public/browser/browser_context.h" | 25 #include "content/public/browser/browser_context.h" |
25 #include "content/public/browser/content_browser_client.h" | 26 #include "content/public/browser/content_browser_client.h" |
26 #include "content/public/browser/global_request_id.h" | 27 #include "content/public/browser/global_request_id.h" |
27 #include "content/public/browser/invalidate_type.h" | 28 #include "content/public/browser/invalidate_type.h" |
28 #include "content/public/browser/navigation_controller.h" | 29 #include "content/public/browser/navigation_controller.h" |
29 #include "content/public/browser/navigation_details.h" | 30 #include "content/public/browser/navigation_details.h" |
30 #include "content/public/browser/page_navigator.h" | 31 #include "content/public/browser/page_navigator.h" |
31 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
32 #include "content/public/browser/stream_handle.h" | 33 #include "content/public/browser/stream_handle.h" |
33 #include "content/public/browser/user_metrics.h" | 34 #include "content/public/browser/user_metrics.h" |
34 #include "content/public/common/bindings_policy.h" | 35 #include "content/public/common/bindings_policy.h" |
35 #include "content/public/common/content_client.h" | 36 #include "content/public/common/content_client.h" |
36 #include "content/public/common/content_switches.h" | 37 #include "content/public/common/content_switches.h" |
37 #include "content/public/common/resource_response.h" | 38 #include "content/public/common/resource_response.h" |
38 #include "content/public/common/url_constants.h" | 39 #include "content/public/common/url_constants.h" |
39 #include "content/public/common/url_utils.h" | 40 #include "content/public/common/url_utils.h" |
40 #include "net/base/load_flags.h" | |
41 #include "net/http/http_request_headers.h" | |
42 | 41 |
43 namespace content { | 42 namespace content { |
44 | 43 |
45 namespace { | 44 namespace { |
46 | 45 |
47 FrameMsg_Navigate_Type::Value GetNavigationType( | 46 FrameMsg_Navigate_Type::Value GetNavigationType( |
48 BrowserContext* browser_context, const NavigationEntryImpl& entry, | 47 BrowserContext* browser_context, const NavigationEntryImpl& entry, |
49 NavigationController::ReloadType reload_type) { | 48 NavigationController::ReloadType reload_type) { |
50 switch (reload_type) { | 49 switch (reload_type) { |
51 case NavigationControllerImpl::RELOAD: | 50 case NavigationControllerImpl::RELOAD: |
(...skipping 11 matching lines...) Expand all Loading... | |
63 if (entry.restore_type() == | 62 if (entry.restore_type() == |
64 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY) { | 63 NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY) { |
65 if (entry.GetHasPostData()) | 64 if (entry.GetHasPostData()) |
66 return FrameMsg_Navigate_Type::RESTORE_WITH_POST; | 65 return FrameMsg_Navigate_Type::RESTORE_WITH_POST; |
67 return FrameMsg_Navigate_Type::RESTORE; | 66 return FrameMsg_Navigate_Type::RESTORE; |
68 } | 67 } |
69 | 68 |
70 return FrameMsg_Navigate_Type::NORMAL; | 69 return FrameMsg_Navigate_Type::NORMAL; |
71 } | 70 } |
72 | 71 |
73 // PlzNavigate | |
74 // Returns the net load flags to use based on the navigation type. | |
75 // TODO(clamy): unify the code with what is happening on the renderer side. | |
76 int LoadFlagFromNavigationType(FrameMsg_Navigate_Type::Value navigation_type) { | |
77 int load_flags = net::LOAD_NORMAL; | |
78 switch (navigation_type) { | |
79 case FrameMsg_Navigate_Type::RELOAD: | |
80 case FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL: | |
81 load_flags |= net::LOAD_VALIDATE_CACHE; | |
82 break; | |
83 case FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE: | |
84 load_flags |= net::LOAD_BYPASS_CACHE; | |
85 break; | |
86 case FrameMsg_Navigate_Type::RESTORE: | |
87 load_flags |= net::LOAD_PREFERRING_CACHE; | |
88 break; | |
89 case FrameMsg_Navigate_Type::RESTORE_WITH_POST: | |
90 load_flags |= net::LOAD_ONLY_FROM_CACHE; | |
91 break; | |
92 case FrameMsg_Navigate_Type::NORMAL: | |
93 default: | |
94 break; | |
95 } | |
96 return load_flags; | |
97 } | |
98 | |
99 // PlzNavigate | |
100 // Generates a default FrameHostMsg_BeginNavigation_Params to be used when there | |
101 // is no live renderer. | |
102 FrameHostMsg_BeginNavigation_Params MakeDefaultBeginNavigation( | |
103 const RequestNavigationParams& request_params, | |
104 FrameMsg_Navigate_Type::Value navigation_type) { | |
105 FrameHostMsg_BeginNavigation_Params begin_navigation_params; | |
106 begin_navigation_params.method = request_params.is_post ? "POST" : "GET"; | |
107 begin_navigation_params.load_flags = | |
108 LoadFlagFromNavigationType(navigation_type); | |
109 | |
110 // Copy existing headers and add necessary headers that may not be present | |
111 // in the RequestNavigationParams. | |
112 net::HttpRequestHeaders headers; | |
113 headers.AddHeadersFromString(request_params.extra_headers); | |
114 headers.SetHeaderIfMissing(net::HttpRequestHeaders::kUserAgent, | |
115 GetContentClient()->GetUserAgent()); | |
116 headers.SetHeaderIfMissing("Accept", "*/*"); | |
117 begin_navigation_params.headers = headers.ToString(); | |
118 | |
119 // Fill POST data from the browser in the request body. | |
120 if (request_params.is_post) { | |
121 begin_navigation_params.request_body = new ResourceRequestBody(); | |
122 begin_navigation_params.request_body->AppendBytes( | |
123 reinterpret_cast<const char *>( | |
124 &request_params.browser_initiated_post_data.front()), | |
125 request_params.browser_initiated_post_data.size()); | |
126 } | |
127 | |
128 begin_navigation_params.has_user_gesture = false; | |
129 return begin_navigation_params; | |
130 } | |
131 | |
132 RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { | 72 RenderFrameHostManager* GetRenderManager(RenderFrameHostImpl* rfh) { |
133 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 73 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
134 switches::kSitePerProcess)) | 74 switches::kSitePerProcess)) |
135 return rfh->frame_tree_node()->render_manager(); | 75 return rfh->frame_tree_node()->render_manager(); |
136 | 76 |
137 return rfh->frame_tree_node()->frame_tree()->root()->render_manager(); | 77 return rfh->frame_tree_node()->frame_tree()->root()->render_manager(); |
138 } | 78 } |
139 | 79 |
140 void MakeNavigateParams(const NavigationEntryImpl& entry, | 80 void MakeNavigateParams(const NavigationEntryImpl& entry, |
141 NavigationControllerImpl* controller, | 81 NavigationControllerImpl* controller, |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
739 | 679 |
740 // Navigations in Web UI pages count as browser-initiated navigations. | 680 // Navigations in Web UI pages count as browser-initiated navigations. |
741 params.is_renderer_initiated = false; | 681 params.is_renderer_initiated = false; |
742 } | 682 } |
743 | 683 |
744 if (delegate_) | 684 if (delegate_) |
745 delegate_->RequestOpenURL(render_frame_host, params); | 685 delegate_->RequestOpenURL(render_frame_host, params); |
746 } | 686 } |
747 | 687 |
748 // PlzNavigate | 688 // PlzNavigate |
749 void NavigatorImpl::OnBeginNavigation( | 689 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, |
750 FrameTreeNode* frame_tree_node, | 690 bool proceed) { |
751 const FrameHostMsg_BeginNavigation_Params& params, | |
752 const CommonNavigationParams& common_params) { | |
753 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 691 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
754 switches::kEnableBrowserSideNavigation)); | 692 switches::kEnableBrowserSideNavigation)); |
755 DCHECK(frame_tree_node); | 693 DCHECK(frame_tree_node); |
756 | 694 |
757 NavigationRequest* navigation_request = | 695 NavigationRequest* navigation_request = |
758 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); | 696 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); |
759 | 697 |
760 if (!navigation_request) { | 698 // The NavigationRequest may have been canceled while the renderer was |
761 // This is a renderer initiated navigation, so generate a new | 699 // executing the BeforeUnload event. |
762 // NavigationRequest and store it in the map. | 700 if (!navigation_request) |
763 // TODO(clamy): Check if some PageState should be provided here. | 701 return; |
764 // TODO(clamy): See how we should handle override of the user agent when the | |
765 // navigation may start in a renderer and commit in another one. | |
766 // TODO(clamy): See if the navigation start time should be measured in the | |
767 // renderer and sent to the browser instead of being measured here. | |
768 scoped_ptr<NavigationRequest> scoped_request(new NavigationRequest( | |
769 frame_tree_node, common_params, | |
770 CommitNavigationParams(PageState(), false, base::TimeTicks::Now()), | |
771 nullptr)); | |
772 navigation_request = scoped_request.get(); | |
773 navigation_request_map_.set( | |
774 frame_tree_node->frame_tree_node_id(), scoped_request.Pass()); | |
775 } | |
776 DCHECK(navigation_request); | |
777 | 702 |
778 // Update the referrer with the one received from the renderer. | 703 DCHECK(navigation_request->state() == |
779 navigation_request->common_params().referrer = common_params.referrer; | 704 NavigationRequest::WAITING_FOR_RENDERER_RESPONSE); |
davidben
2015/02/03 02:23:21
Nit: DCHECK_EQ
carlosk
2015/02/03 16:06:02
Isn't it possible that the original request was ca
clamy
2015/02/03 16:17:09
Yes but in that case we do not send another Before
clamy
2015/02/03 16:17:09
Done.
| |
780 | 705 |
781 scoped_ptr<NavigationRequestInfo> info(new NavigationRequestInfo(params)); | 706 if (proceed) |
782 | 707 BeginNavigation(frame_tree_node); |
783 info->first_party_for_cookies = | 708 else |
784 frame_tree_node->IsMainFrame() | 709 CancelNavigation(frame_tree_node); |
785 ? navigation_request->common_params().url | |
786 : frame_tree_node->frame_tree()->root()->current_url(); | |
787 info->is_main_frame = frame_tree_node->IsMainFrame(); | |
788 info->parent_is_main_frame = !frame_tree_node->parent() ? | |
789 false : frame_tree_node->parent()->IsMainFrame(); | |
790 | |
791 // First start the request on the IO thread. | |
792 navigation_request->BeginNavigation(info.Pass(), params.request_body); | |
793 | |
794 // Then notify the RenderFrameHostManager so it can speculatively create a | |
795 // RenderFrameHost (and potentially a new renderer process) in parallel. | |
796 frame_tree_node->render_manager()->BeginNavigation(*navigation_request); | |
797 } | 710 } |
798 | 711 |
799 // PlzNavigate | 712 // PlzNavigate |
713 void NavigatorImpl::OnBeginNavigation( | |
714 FrameTreeNode* frame_tree_node, | |
715 const CommonNavigationParams& common_params, | |
716 const BeginNavigationParams& begin_params, | |
717 scoped_refptr<ResourceRequestBody> body) { | |
718 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | |
719 switches::kEnableBrowserSideNavigation)); | |
720 DCHECK(frame_tree_node); | |
721 | |
722 // This is a renderer initiated navigation, so generate a new | |
nasko
2015/02/02 21:17:43
nit: renderer-initiated
clamy
2015/02/03 16:17:09
Done.
| |
723 // NavigationRequest and store it in the map. | |
724 // TODO(clamy): Renderer-initiated navigations should not always cancel the | |
725 // current one. | |
726 scoped_ptr<NavigationRequest> navigation_request = | |
727 NavigationRequest::CreateRendererInitiated( | |
728 frame_tree_node, common_params, begin_params, body); | |
729 navigation_request_map_.set( | |
carlosk
2015/02/03 16:06:02
Don't we need to verify first if another request i
clamy
2015/02/03 16:17:09
That's the TODO above this block of code. The patc
| |
730 frame_tree_node->frame_tree_node_id(), navigation_request.Pass()); | |
731 | |
732 BeginNavigation(frame_tree_node); | |
733 } | |
734 | |
735 // PlzNavigate | |
800 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, | 736 void NavigatorImpl::CommitNavigation(FrameTreeNode* frame_tree_node, |
801 ResourceResponse* response, | 737 ResourceResponse* response, |
802 scoped_ptr<StreamHandle> body) { | 738 scoped_ptr<StreamHandle> body) { |
803 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 739 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
804 switches::kEnableBrowserSideNavigation)); | 740 switches::kEnableBrowserSideNavigation)); |
805 | 741 |
806 // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not | 742 // HTTP 204 (No Content) and HTTP 205 (Reset Content) responses should not |
807 // commit; they leave the frame showing the previous page. | 743 // commit; they leave the frame showing the previous page. |
808 if (response->head.headers.get() && | 744 if (response->head.headers.get() && |
809 (response->head.headers->response_code() == 204 || | 745 (response->head.headers->response_code() == 204 || |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
898 FrameTreeNode* frame_tree_node, | 834 FrameTreeNode* frame_tree_node, |
899 const NavigationEntryImpl& entry, | 835 const NavigationEntryImpl& entry, |
900 NavigationController::ReloadType reload_type, | 836 NavigationController::ReloadType reload_type, |
901 base::TimeTicks navigation_start) { | 837 base::TimeTicks navigation_start) { |
902 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 838 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
903 switches::kEnableBrowserSideNavigation)); | 839 switches::kEnableBrowserSideNavigation)); |
904 DCHECK(frame_tree_node); | 840 DCHECK(frame_tree_node); |
905 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); | 841 int64 frame_tree_node_id = frame_tree_node->frame_tree_node_id(); |
906 FrameMsg_Navigate_Type::Value navigation_type = | 842 FrameMsg_Navigate_Type::Value navigation_type = |
907 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); | 843 GetNavigationType(controller_->GetBrowserContext(), entry, reload_type); |
908 scoped_ptr<NavigationRequest> navigation_request = NavigationRequest::Create( | 844 scoped_ptr<NavigationRequest> navigation_request = |
909 frame_tree_node, entry, navigation_type, navigation_start); | 845 NavigationRequest::CreateBrowserInitiated( |
910 RequestNavigationParams request_params(entry.GetHasPostData(), | 846 frame_tree_node, entry, navigation_type, navigation_start); |
911 entry.extra_headers(), | |
912 entry.GetBrowserInitiatedPostData()); | |
913 // TODO(clamy): Check if navigations are blocked and if so store the | 847 // TODO(clamy): Check if navigations are blocked and if so store the |
914 // parameters. | 848 // parameters. |
915 | 849 |
916 // If there is an ongoing request, replace it. | 850 // If there is an ongoing request, replace it. |
917 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); | 851 navigation_request_map_.set(frame_tree_node_id, navigation_request.Pass()); |
918 | 852 |
919 if (frame_tree_node->current_frame_host()->IsRenderFrameLive()) { | 853 // Have the current renderer execute its BeforeUnload event if needed. If it |
nasko
2015/02/02 21:17:43
nit: beforeUnload
clamy
2015/02/03 16:17:09
Done.
| |
920 NavigationRequest* request_to_send = | 854 // is not needed (eg. the renderer is not live), BeginNavigation should get |
921 navigation_request_map_.get(frame_tree_node_id); | 855 // called. |
922 frame_tree_node->current_frame_host()->Send(new FrameMsg_RequestNavigation( | 856 NavigationRequest* request_to_send = |
923 frame_tree_node->current_frame_host()->GetRoutingID(), | 857 navigation_request_map_.get(frame_tree_node_id); |
924 request_to_send->common_params(), request_params)); | 858 request_to_send->SetWaitingForRendererResponse(); |
925 request_to_send->SetWaitingForRendererResponse(); | 859 frame_tree_node->current_frame_host()->DispatchBeforeUnload(true); |
nasko
2015/02/02 21:17:43
Do we know this is a cross-site transition? It cou
davidben
2015/02/03 02:23:21
Even if the navigation is same-site, I think we'll
clamy
2015/02/03 16:17:09
My understanding is that this flag is used by Rend
nasko
2015/02/04 00:14:19
Indeed renaming it makes sense.
clamy
2015/02/05 15:33:13
Included the renaming in this CL.
| |
926 return true; | 860 return true; |
carlosk
2015/02/03 16:06:02
This return doesn't seem to be meaningful anymore.
clamy
2015/02/03 16:17:09
We either always return true here, or in NavigateT
nasko
2015/02/04 00:14:19
If this method cannot fail, it shouldn't be return
clamy
2015/02/05 15:33:13
It's a simple enough change, so including it in th
| |
927 } | 861 } |
928 | 862 |
929 // The navigation request is sent directly to the IO thread. | 863 void NavigatorImpl::BeginNavigation(FrameTreeNode* frame_tree_node) { |
930 OnBeginNavigation( | 864 NavigationRequest* navigation_request = |
931 frame_tree_node, | 865 navigation_request_map_.get(frame_tree_node->frame_tree_node_id()); |
932 MakeDefaultBeginNavigation(request_params, navigation_type), | 866 |
933 navigation_request_map_.get(frame_tree_node_id)->common_params()); | 867 // A browser-initiated navigation could have been cancelled while it was |
934 return true; | 868 // waiting for the BeforeUnload event to execute. |
869 if (!navigation_request) | |
870 return; | |
871 | |
872 // First start the request on the IO thread. | |
873 navigation_request->BeginNavigation(); | |
874 | |
875 // Then notify the RenderFrameHostManager so it can speculatively create a | |
876 // RenderFrameHost (and potentially a new renderer process) in parallel. | |
877 frame_tree_node->render_manager()->BeginNavigation(*navigation_request); | |
935 } | 878 } |
936 | 879 |
937 void NavigatorImpl::RecordNavigationMetrics( | 880 void NavigatorImpl::RecordNavigationMetrics( |
938 const LoadCommittedDetails& details, | 881 const LoadCommittedDetails& details, |
939 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 882 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
940 SiteInstance* site_instance) { | 883 SiteInstance* site_instance) { |
941 DCHECK(site_instance->HasProcess()); | 884 DCHECK(site_instance->HasProcess()); |
942 | 885 |
943 if (!details.is_in_page) | 886 if (!details.is_in_page) |
944 RecordAction(base::UserMetricsAction("FrameLoad")); | 887 RecordAction(base::UserMetricsAction("FrameLoad")); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
981 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", | 924 "Navigation.TimeToCommit_ExistingRenderer_BeforeUnloadDiscounted", |
982 time_to_commit); | 925 time_to_commit); |
983 UMA_HISTOGRAM_TIMES( | 926 UMA_HISTOGRAM_TIMES( |
984 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", | 927 "Navigation.TimeToURLJobStart_ExistingRenderer_BeforeUnloadDiscounted", |
985 time_to_network); | 928 time_to_network); |
986 } | 929 } |
987 navigation_data_.reset(); | 930 navigation_data_.reset(); |
988 } | 931 } |
989 | 932 |
990 } // namespace content | 933 } // namespace content |
OLD | NEW |