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/renderer/render_frame_impl.h" | 5 #include "content/renderer/render_frame_impl.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 } | 1070 } |
1071 | 1071 |
1072 void RenderFrameImpl::OnNavigate( | 1072 void RenderFrameImpl::OnNavigate( |
1073 const CommonNavigationParams& common_params, | 1073 const CommonNavigationParams& common_params, |
1074 const StartNavigationParams& start_params, | 1074 const StartNavigationParams& start_params, |
1075 const RequestNavigationParams& request_params) { | 1075 const RequestNavigationParams& request_params) { |
1076 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( | 1076 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( |
1077 switches::kEnableBrowserSideNavigation)); | 1077 switches::kEnableBrowserSideNavigation)); |
1078 TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate", "id", routing_id_, | 1078 TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate", "id", routing_id_, |
1079 "url", common_params.url.possibly_invalid_spec()); | 1079 "url", common_params.url.possibly_invalid_spec()); |
1080 | 1080 NavigateInternal(common_params, start_params, request_params, |
1081 bool is_reload = IsReload(common_params.navigation_type); | 1081 scoped_ptr<StreamOverrideParameters>()); |
1082 bool is_history_navigation = request_params.page_state.IsValid(); | |
1083 WebURLRequest::CachePolicy cache_policy = | |
1084 WebURLRequest::UseProtocolCachePolicy; | |
1085 if (!RenderFrameImpl::PrepareRenderViewForNavigation( | |
1086 common_params.url, is_history_navigation, request_params, &is_reload, | |
1087 &cache_policy)) { | |
1088 Send(new FrameHostMsg_DidDropNavigation(routing_id_)); | |
1089 return; | |
1090 } | |
1091 | |
1092 GetContentClient()->SetActiveURL(common_params.url); | |
1093 | |
1094 if (is_reload && !render_view_->history_controller()->GetCurrentEntry()) { | |
1095 // We cannot reload if we do not have any history state. This happens, for | |
1096 // example, when recovering from a crash. | |
1097 is_reload = false; | |
1098 cache_policy = WebURLRequest::ReloadIgnoringCacheData; | |
1099 } | |
1100 | |
1101 pending_navigation_params_.reset( | |
1102 new NavigationParams(common_params, start_params, request_params)); | |
1103 | |
1104 // If we are reloading, then WebKit will use the history state of the current | |
1105 // page, so we should just ignore any given history state. Otherwise, if we | |
1106 // have history state, then we need to navigate to it, which corresponds to a | |
1107 // back/forward navigation event. | |
1108 if (is_reload) { | |
1109 bool reload_original_url = | |
1110 (common_params.navigation_type == | |
1111 FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL); | |
1112 bool ignore_cache = (common_params.navigation_type == | |
1113 FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE); | |
1114 | |
1115 if (reload_original_url) | |
1116 frame_->reloadWithOverrideURL(common_params.url, true); | |
1117 else | |
1118 frame_->reload(ignore_cache); | |
1119 } else if (is_history_navigation) { | |
1120 // We must know the page ID of the page we are navigating back to. | |
1121 DCHECK_NE(request_params.page_id, -1); | |
1122 scoped_ptr<HistoryEntry> entry = | |
1123 PageStateToHistoryEntry(request_params.page_state); | |
1124 if (entry) { | |
1125 // Ensure we didn't save the swapped out URL in UpdateState, since the | |
1126 // browser should never be telling us to navigate to swappedout://. | |
1127 CHECK(entry->root().urlString() != WebString::fromUTF8(kSwappedOutURL)); | |
1128 scoped_ptr<NavigationParams> navigation_params( | |
1129 new NavigationParams(*pending_navigation_params_.get())); | |
1130 render_view_->history_controller()->GoToEntry( | |
1131 entry.Pass(), navigation_params.Pass(), cache_policy); | |
1132 } | |
1133 } else if (!common_params.base_url_for_data_url.is_empty()) { | |
1134 LoadDataURL(common_params, frame_); | |
1135 } else { | |
1136 // Navigate to the given URL. | |
1137 WebURLRequest request = CreateURLRequestForNavigation( | |
1138 common_params, scoped_ptr<StreamOverrideParameters>(), | |
1139 frame_->isViewSourceModeEnabled()); | |
1140 | |
1141 if (!start_params.extra_headers.empty()) { | |
1142 for (net::HttpUtil::HeadersIterator i(start_params.extra_headers.begin(), | |
1143 start_params.extra_headers.end(), | |
1144 "\n"); | |
1145 i.GetNext();) { | |
1146 request.addHTTPHeaderField(WebString::fromUTF8(i.name()), | |
1147 WebString::fromUTF8(i.values())); | |
1148 } | |
1149 } | |
1150 | |
1151 if (start_params.is_post) { | |
1152 request.setHTTPMethod(WebString::fromUTF8("POST")); | |
1153 | |
1154 // Set post data. | |
1155 WebHTTPBody http_body; | |
1156 http_body.initialize(); | |
1157 const char* data = NULL; | |
1158 if (start_params.browser_initiated_post_data.size()) { | |
1159 data = reinterpret_cast<const char*>( | |
1160 &start_params.browser_initiated_post_data.front()); | |
1161 } | |
1162 http_body.appendData( | |
1163 WebData(data, start_params.browser_initiated_post_data.size())); | |
1164 request.setHTTPBody(http_body); | |
1165 } | |
1166 | |
1167 // A session history navigation should have been accompanied by state. | |
1168 CHECK_EQ(request_params.page_id, -1); | |
1169 | |
1170 // Record this before starting the load, we need a lower bound of this time | |
1171 // to sanitize the navigationStart override set below. | |
1172 base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); | |
1173 frame_->loadRequest(request); | |
1174 | |
1175 UpdateFrameNavigationTiming(frame_, request_params.browser_navigation_start, | |
1176 renderer_navigation_start); | |
1177 } | |
1178 | |
1179 // In case LoadRequest failed before didCreateDataSource was called. | |
1180 pending_navigation_params_.reset(); | |
1181 } | 1082 } |
1182 | 1083 |
1183 void RenderFrameImpl::NavigateToSwappedOutURL() { | 1084 void RenderFrameImpl::NavigateToSwappedOutURL() { |
1184 // We use loadRequest instead of loadHTMLString because the former commits | 1085 // We use loadRequest instead of loadHTMLString because the former commits |
1185 // synchronously. Otherwise a new navigation can interrupt the navigation | 1086 // synchronously. Otherwise a new navigation can interrupt the navigation |
1186 // to kSwappedOutURL. If that happens to be to the page we had been | 1087 // to kSwappedOutURL. If that happens to be to the page we had been |
1187 // showing, then WebKit will never send a commit and we'll be left spinning. | 1088 // showing, then WebKit will never send a commit and we'll be left spinning. |
1188 // Set the is_swapped_out_ bit to true, so IPC filtering is in effect and | 1089 // Set the is_swapped_out_ bit to true, so IPC filtering is in effect and |
1189 // the navigation to swappedout:// is not announced to the browser side. | 1090 // the navigation to swappedout:// is not announced to the browser side. |
1190 is_swapped_out_ = true; | 1091 is_swapped_out_ = true; |
(...skipping 2880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 } | 3972 } |
4072 | 3973 |
4073 // PlzNavigate | 3974 // PlzNavigate |
4074 void RenderFrameImpl::OnCommitNavigation( | 3975 void RenderFrameImpl::OnCommitNavigation( |
4075 const ResourceResponseHead& response, | 3976 const ResourceResponseHead& response, |
4076 const GURL& stream_url, | 3977 const GURL& stream_url, |
4077 const CommonNavigationParams& common_params, | 3978 const CommonNavigationParams& common_params, |
4078 const RequestNavigationParams& request_params) { | 3979 const RequestNavigationParams& request_params) { |
4079 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 3980 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
4080 switches::kEnableBrowserSideNavigation)); | 3981 switches::kEnableBrowserSideNavigation)); |
4081 bool is_reload = false; | 3982 // This will override the url requested by the WebURLLoader, as well as |
4082 bool is_history_navigation = request_params.page_state.IsValid(); | 3983 // provide it with the response to the request. |
4083 WebURLRequest::CachePolicy cache_policy = | |
4084 WebURLRequest::UseProtocolCachePolicy; | |
4085 if (!RenderFrameImpl::PrepareRenderViewForNavigation( | |
4086 common_params.url, is_history_navigation, request_params, &is_reload, | |
4087 &cache_policy)) { | |
4088 Send(new FrameHostMsg_DidDropNavigation(routing_id_)); | |
4089 return; | |
4090 } | |
4091 | |
4092 GetContentClient()->SetActiveURL(common_params.url); | |
4093 | |
4094 pending_navigation_params_.reset(new NavigationParams( | |
4095 common_params, StartNavigationParams(), request_params)); | |
4096 | |
4097 if (!common_params.base_url_for_data_url.is_empty() || | |
4098 common_params.url.SchemeIs(url::kDataScheme)) { | |
4099 LoadDataURL(common_params, frame_); | |
4100 return; | |
4101 } | |
4102 | |
4103 // Create a WebURLRequest that blink can use to get access to the body of the | |
4104 // response through a stream in the browser. Blink will then commit the | |
4105 // navigation. | |
4106 // TODO(clamy): Have the navigation commit directly, without going through | |
4107 // loading a WebURLRequest. | |
4108 scoped_ptr<StreamOverrideParameters> stream_override( | 3984 scoped_ptr<StreamOverrideParameters> stream_override( |
4109 new StreamOverrideParameters()); | 3985 new StreamOverrideParameters()); |
4110 stream_override->stream_url = stream_url; | 3986 stream_override->stream_url = stream_url; |
4111 stream_override->response = response; | 3987 stream_override->response = response; |
4112 WebURLRequest request = | |
4113 CreateURLRequestForNavigation(common_params, | |
4114 stream_override.Pass(), | |
4115 frame_->isViewSourceModeEnabled()); | |
4116 | 3988 |
4117 // Make sure that blink loader will not try to use browser side navigation for | 3989 NavigateInternal(common_params, StartNavigationParams(), request_params, |
4118 // this request (since it already went to the browser). | 3990 stream_override.Pass()); |
4119 request.setCheckForBrowserSideNavigation(false); | |
4120 | |
4121 // Record this before starting the load. A lower bound of this time is needed | |
4122 // to sanitize the navigationStart override set below. | |
4123 base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); | |
4124 frame_->loadRequest(request); | |
4125 UpdateFrameNavigationTiming(frame_, request_params.browser_navigation_start, | |
4126 renderer_navigation_start); | |
4127 } | 3991 } |
4128 | 3992 |
4129 void RenderFrameImpl::OnFailedNavigation( | 3993 void RenderFrameImpl::OnFailedNavigation( |
4130 const CommonNavigationParams& common_params, | 3994 const CommonNavigationParams& common_params, |
4131 const RequestNavigationParams& request_params, | 3995 const RequestNavigationParams& request_params, |
4132 bool has_stale_copy_in_cache, | 3996 bool has_stale_copy_in_cache, |
4133 int error_code) { | 3997 int error_code) { |
4134 bool is_reload = IsReload(common_params.navigation_type); | 3998 bool is_reload = IsReload(common_params.navigation_type); |
4135 bool is_history_navigation = request_params.page_state.IsValid(); | 3999 bool is_history_navigation = request_params.page_state.IsValid(); |
4136 WebURLRequest::CachePolicy cache_policy = | 4000 WebURLRequest::CachePolicy cache_policy = |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4449 if (policy == blink::WebNavigationPolicyNewBackgroundTab || | 4313 if (policy == blink::WebNavigationPolicyNewBackgroundTab || |
4450 policy == blink::WebNavigationPolicyNewForegroundTab || | 4314 policy == blink::WebNavigationPolicyNewForegroundTab || |
4451 policy == blink::WebNavigationPolicyNewWindow || | 4315 policy == blink::WebNavigationPolicyNewWindow || |
4452 policy == blink::WebNavigationPolicyNewPopup) { | 4316 policy == blink::WebNavigationPolicyNewPopup) { |
4453 WebUserGestureIndicator::consumeUserGesture(); | 4317 WebUserGestureIndicator::consumeUserGesture(); |
4454 } | 4318 } |
4455 | 4319 |
4456 Send(new FrameHostMsg_OpenURL(routing_id_, params)); | 4320 Send(new FrameHostMsg_OpenURL(routing_id_, params)); |
4457 } | 4321 } |
4458 | 4322 |
| 4323 void RenderFrameImpl::NavigateInternal( |
| 4324 const CommonNavigationParams& common_params, |
| 4325 const StartNavigationParams& start_params, |
| 4326 const RequestNavigationParams& request_params, |
| 4327 scoped_ptr<StreamOverrideParameters> stream_params) { |
| 4328 bool browser_side_navigation = |
| 4329 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 4330 switches::kEnableBrowserSideNavigation); |
| 4331 bool is_reload = IsReload(common_params.navigation_type); |
| 4332 bool is_history_navigation = request_params.page_state.IsValid(); |
| 4333 WebURLRequest::CachePolicy cache_policy = |
| 4334 WebURLRequest::UseProtocolCachePolicy; |
| 4335 if (!RenderFrameImpl::PrepareRenderViewForNavigation( |
| 4336 common_params.url, is_history_navigation, request_params, &is_reload, |
| 4337 &cache_policy)) { |
| 4338 Send(new FrameHostMsg_DidDropNavigation(routing_id_)); |
| 4339 return; |
| 4340 } |
| 4341 |
| 4342 GetContentClient()->SetActiveURL(common_params.url); |
| 4343 |
| 4344 if (is_reload && !render_view_->history_controller()->GetCurrentEntry()) { |
| 4345 // We cannot reload if we do not have any history state. This happens, for |
| 4346 // example, when recovering from a crash. |
| 4347 is_reload = false; |
| 4348 cache_policy = WebURLRequest::ReloadIgnoringCacheData; |
| 4349 } |
| 4350 |
| 4351 pending_navigation_params_.reset( |
| 4352 new NavigationParams(common_params, start_params, request_params)); |
| 4353 |
| 4354 // If we are reloading, then Blink will use the history state of the current |
| 4355 // page, so we should just ignore any given history state. Otherwise, if we |
| 4356 // have history state, then we need to navigate to it, which corresponds to a |
| 4357 // back/forward navigation event. |
| 4358 if (is_reload && !browser_side_navigation) { |
| 4359 // TODO(clamy): adapt this code for PlzNavigate. In particular the stream |
| 4360 // override should be given to the generated request. |
| 4361 bool reload_original_url = |
| 4362 (common_params.navigation_type == |
| 4363 FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL); |
| 4364 bool ignore_cache = (common_params.navigation_type == |
| 4365 FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE); |
| 4366 |
| 4367 if (reload_original_url) |
| 4368 frame_->reloadWithOverrideURL(common_params.url, true); |
| 4369 else |
| 4370 frame_->reload(ignore_cache); |
| 4371 } else if (is_history_navigation && !browser_side_navigation) { |
| 4372 // TODO(clamy): adapt this code for PlzNavigate. In particular the stream |
| 4373 // override should be given to the generated request. |
| 4374 |
| 4375 // We must know the page ID of the page we are navigating back to. |
| 4376 DCHECK_NE(request_params.page_id, -1); |
| 4377 scoped_ptr<HistoryEntry> entry = |
| 4378 PageStateToHistoryEntry(request_params.page_state); |
| 4379 if (entry) { |
| 4380 // Ensure we didn't save the swapped out URL in UpdateState, since the |
| 4381 // browser should never be telling us to navigate to swappedout://. |
| 4382 CHECK(entry->root().urlString() != WebString::fromUTF8(kSwappedOutURL)); |
| 4383 scoped_ptr<NavigationParams> navigation_params( |
| 4384 new NavigationParams(*pending_navigation_params_.get())); |
| 4385 render_view_->history_controller()->GoToEntry( |
| 4386 entry.Pass(), navigation_params.Pass(), cache_policy); |
| 4387 } |
| 4388 } else if (!common_params.base_url_for_data_url.is_empty() || |
| 4389 (browser_side_navigation && |
| 4390 common_params.url.SchemeIs(url::kDataScheme))) { |
| 4391 LoadDataURL(common_params, frame_); |
| 4392 } else { |
| 4393 // Navigate to the given URL. |
| 4394 WebURLRequest request = CreateURLRequestForNavigation( |
| 4395 common_params, stream_params.Pass(), frame_->isViewSourceModeEnabled()); |
| 4396 |
| 4397 if (!start_params.extra_headers.empty() && !browser_side_navigation) { |
| 4398 for (net::HttpUtil::HeadersIterator i(start_params.extra_headers.begin(), |
| 4399 start_params.extra_headers.end(), |
| 4400 "\n"); |
| 4401 i.GetNext();) { |
| 4402 request.addHTTPHeaderField(WebString::fromUTF8(i.name()), |
| 4403 WebString::fromUTF8(i.values())); |
| 4404 } |
| 4405 } |
| 4406 |
| 4407 if (start_params.is_post && !browser_side_navigation) { |
| 4408 request.setHTTPMethod(WebString::fromUTF8("POST")); |
| 4409 |
| 4410 // Set post data. |
| 4411 WebHTTPBody http_body; |
| 4412 http_body.initialize(); |
| 4413 const char* data = nullptr; |
| 4414 if (start_params.browser_initiated_post_data.size()) { |
| 4415 data = reinterpret_cast<const char*>( |
| 4416 &start_params.browser_initiated_post_data.front()); |
| 4417 } |
| 4418 http_body.appendData( |
| 4419 WebData(data, start_params.browser_initiated_post_data.size())); |
| 4420 request.setHTTPBody(http_body); |
| 4421 } |
| 4422 |
| 4423 // A session history navigation should have been accompanied by state. |
| 4424 CHECK_EQ(request_params.page_id, -1); |
| 4425 |
| 4426 // PlzNavigate: Make sure that Blink's loader will not try to use browser |
| 4427 // side navigation for this request (since it already went to the browser). |
| 4428 if (browser_side_navigation) |
| 4429 request.setCheckForBrowserSideNavigation(false); |
| 4430 |
| 4431 // Record this before starting the load. We need a lower bound of this time |
| 4432 // to sanitize the navigationStart override set below. |
| 4433 base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); |
| 4434 frame_->loadRequest(request); |
| 4435 |
| 4436 UpdateFrameNavigationTiming(frame_, request_params.browser_navigation_start, |
| 4437 renderer_navigation_start); |
| 4438 } |
| 4439 |
| 4440 // In case LoadRequest failed before didCreateDataSource was called. |
| 4441 pending_navigation_params_.reset(); |
| 4442 } |
| 4443 |
4459 void RenderFrameImpl::UpdateEncoding(WebFrame* frame, | 4444 void RenderFrameImpl::UpdateEncoding(WebFrame* frame, |
4460 const std::string& encoding_name) { | 4445 const std::string& encoding_name) { |
4461 // Only update main frame's encoding_name. | 4446 // Only update main frame's encoding_name. |
4462 if (!frame->parent()) | 4447 if (!frame->parent()) |
4463 Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name)); | 4448 Send(new FrameHostMsg_UpdateEncoding(routing_id_, encoding_name)); |
4464 } | 4449 } |
4465 | 4450 |
4466 void RenderFrameImpl::SyncSelectionIfRequired() { | 4451 void RenderFrameImpl::SyncSelectionIfRequired() { |
4467 base::string16 text; | 4452 base::string16 text; |
4468 size_t offset; | 4453 size_t offset; |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4853 #elif defined(ENABLE_BROWSER_CDMS) | 4838 #elif defined(ENABLE_BROWSER_CDMS) |
4854 cdm_manager_, | 4839 cdm_manager_, |
4855 #endif | 4840 #endif |
4856 this); | 4841 this); |
4857 } | 4842 } |
4858 | 4843 |
4859 return cdm_factory_; | 4844 return cdm_factory_; |
4860 } | 4845 } |
4861 | 4846 |
4862 } // namespace content | 4847 } // namespace content |
OLD | NEW |