Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(767)

Side by Side Diff: content/browser/frame_host/render_frame_host_impl.cc

Issue 135723003: Move DidCommitProvisionalLoad code from RenderView to RenderFrame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed unit tests and removed WebContents::DidNavigate Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/render_frame_host_impl.h" 5 #include "content/browser/frame_host/render_frame_host_impl.h"
6 6
7 #include "base/containers/hash_tables.h" 7 #include "base/containers/hash_tables.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/metrics/user_metrics_action.h"
9 #include "content/browser/frame_host/cross_process_frame_connector.h" 10 #include "content/browser/frame_host/cross_process_frame_connector.h"
10 #include "content/browser/frame_host/frame_tree.h" 11 #include "content/browser/frame_host/frame_tree.h"
11 #include "content/browser/frame_host/frame_tree_node.h" 12 #include "content/browser/frame_host/frame_tree_node.h"
12 #include "content/browser/frame_host/navigator.h" 13 #include "content/browser/frame_host/navigator.h"
13 #include "content/browser/frame_host/render_frame_host_delegate.h" 14 #include "content/browser/frame_host/render_frame_host_delegate.h"
14 #include "content/browser/renderer_host/render_view_host_impl.h" 15 #include "content/browser/renderer_host/render_view_host_impl.h"
15 #include "content/common/frame_messages.h" 16 #include "content/common/frame_messages.h"
16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/content_browser_client.h"
17 #include "content/public/browser/render_process_host.h" 19 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_widget_host_view.h" 20 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/browser/user_metrics.h" 21 #include "content/public/browser/user_metrics.h"
22 #include "content/public/common/url_constants.h"
20 #include "url/gurl.h" 23 #include "url/gurl.h"
21 24
22 namespace content { 25 namespace content {
23 26
24 // The (process id, routing id) pair that identifies one RenderFrame. 27 // The (process id, routing id) pair that identifies one RenderFrame.
25 typedef std::pair<int32, int32> RenderFrameHostID; 28 typedef std::pair<int32, int32> RenderFrameHostID;
26 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*> 29 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*>
27 RoutingIDFrameMap; 30 RoutingIDFrameMap;
28 static base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map = 31 static base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map =
29 LAZY_INSTANCE_INITIALIZER; 32 LAZY_INSTANCE_INITIALIZER;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 bool handled = true; 129 bool handled = true;
127 bool msg_is_ok = true; 130 bool msg_is_ok = true;
128 IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok) 131 IPC_BEGIN_MESSAGE_MAP_EX(RenderFrameHostImpl, msg, msg_is_ok)
129 IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach) 132 IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach)
130 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoadForFrame, 133 IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoadForFrame,
131 OnDidStartProvisionalLoadForFrame) 134 OnDidStartProvisionalLoadForFrame)
132 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError, 135 IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError,
133 OnDidFailProvisionalLoadWithError) 136 OnDidFailProvisionalLoadWithError)
134 IPC_MESSAGE_HANDLER(FrameHostMsg_DidRedirectProvisionalLoad, 137 IPC_MESSAGE_HANDLER(FrameHostMsg_DidRedirectProvisionalLoad,
135 OnDidRedirectProvisionalLoad) 138 OnDidRedirectProvisionalLoad)
139 IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad,
140 OnNavigate(msg))
136 IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK) 141 IPC_MESSAGE_HANDLER(FrameHostMsg_SwapOut_ACK, OnSwapOutACK)
137 IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu) 142 IPC_MESSAGE_HANDLER(FrameHostMsg_ContextMenu, OnContextMenu)
138 IPC_END_MESSAGE_MAP_EX() 143 IPC_END_MESSAGE_MAP_EX()
139 144
140 if (!msg_is_ok) { 145 if (!msg_is_ok) {
141 // The message had a handler, but its de-serialization failed. 146 // The message had a handler, but its de-serialization failed.
142 // Kill the renderer. 147 // Kill the renderer.
143 RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH")); 148 RecordAction(base::UserMetricsAction("BadMessageTerminate_RFH"));
144 GetProcess()->ReceivedBadMessage(); 149 GetProcess()->ReceivedBadMessage();
145 } 150 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 185 }
181 186
182 void RenderFrameHostImpl::OnDidRedirectProvisionalLoad( 187 void RenderFrameHostImpl::OnDidRedirectProvisionalLoad(
183 int32 page_id, 188 int32 page_id,
184 const GURL& source_url, 189 const GURL& source_url,
185 const GURL& target_url) { 190 const GURL& target_url) {
186 frame_tree_node_->navigator()->DidRedirectProvisionalLoad( 191 frame_tree_node_->navigator()->DidRedirectProvisionalLoad(
187 this, page_id, source_url, target_url); 192 this, page_id, source_url, target_url);
188 } 193 }
189 194
195 // Called when the renderer navigates. For every frame loaded, we'll get this
196 // notification containing parameters identifying the navigation.
197 //
198 // Subframes are identified by the page transition type. For subframes loaded
199 // as part of a wider page load, the page_id will be the same as for the top
200 // level frame. If the user explicitly requests a subframe navigation, we will
201 // get a new page_id because we need to create a new navigation entry for that
202 // action.
203 void RenderFrameHostImpl::OnNavigate(const IPC::Message& msg) {
204 // Read the parameters out of the IPC message directly to avoid making another
205 // copy when we filter the URLs.
206 PickleIterator iter(msg);
207 FrameHostMsg_DidCommitProvisionalLoad_Params validated_params;
208 if (!IPC::ParamTraits<FrameHostMsg_DidCommitProvisionalLoad_Params>::
209 Read(&msg, &iter, &validated_params))
210 return;
211
212 // If we're waiting for a cross-site beforeunload ack from this renderer and
213 // we receive a Navigate message from the main frame, then the renderer was
214 // navigating already and sent it before hearing the ViewMsg_Stop message.
215 // We do not want to cancel the pending navigation in this case, since the
216 // old page will soon be stopped. Instead, treat this as a beforeunload ack
217 // to allow the pending navigation to continue.
218 if (render_view_host_->is_waiting_for_beforeunload_ack_ &&
219 render_view_host_->unload_ack_is_for_cross_site_transition_ &&
220 PageTransitionIsMainFrame(validated_params.transition)) {
221 render_view_host_->OnShouldCloseACK(
222 true, render_view_host_->send_should_close_start_time_,
223 base::TimeTicks::Now());
224 return;
225 }
226
227 // If we're waiting for an unload ack from this renderer and we receive a
228 // Navigate message, then the renderer was navigating before it received the
229 // unload request. It will either respond to the unload request soon or our
230 // timer will expire. Either way, we should ignore this message, because we
231 // have already committed to closing this renderer.
232 if (render_view_host_->is_waiting_for_unload_ack_)
233 return;
234
235 // Cache the main frame id, so we can use it for creating the frame tree
236 // root node when needed.
237 if (PageTransitionIsMainFrame(validated_params.transition)) {
238 if (render_view_host_->main_frame_id_ == -1) {
239 render_view_host_->main_frame_id_ = validated_params.frame_id;
240 } else {
241 // TODO(nasko): We plan to remove the usage of frame_id in navigation
242 // and move to routing ids. This is in place to ensure that a
243 // renderer is not misbehaving and sending us incorrect data.
244 DCHECK_EQ(render_view_host_->main_frame_id_, validated_params.frame_id);
245 }
246 }
247 RenderProcessHost* process = GetProcess();
248
249 // Attempts to commit certain off-limits URL should be caught more strictly
250 // than our FilterURL checks below. If a renderer violates this policy, it
251 // should be killed.
252 if (!CanCommitURL(validated_params.url)) {
253 VLOG(1) << "Blocked URL " << validated_params.url.spec();
254 validated_params.url = GURL(kAboutBlankURL);
255 RecordAction(base::UserMetricsAction("CanCommitURL_BlockedAndKilled"));
256 // Kills the process.
257 process->ReceivedBadMessage();
258 }
259
260 // Now that something has committed, we don't need to track whether the
261 // initial page has been accessed.
262 render_view_host_->has_accessed_initial_document_ = false;
263
264 // Without this check, an evil renderer can trick the browser into creating
265 // a navigation entry for a banned URL. If the user clicks the back button
266 // followed by the forward button (or clicks reload, or round-trips through
267 // session restore, etc), we'll think that the browser commanded the
268 // renderer to load the URL and grant the renderer the privileges to request
269 // the URL. To prevent this attack, we block the renderer from inserting
270 // banned URLs into the navigation controller in the first place.
271 process->FilterURL(false, &validated_params.url);
272 process->FilterURL(true, &validated_params.referrer.url);
273 for (std::vector<GURL>::iterator it(validated_params.redirects.begin());
274 it != validated_params.redirects.end(); ++it) {
275 process->FilterURL(false, &(*it));
276 }
277 process->FilterURL(true, &validated_params.searchable_form_url);
278
279 // Without this check, the renderer can trick the browser into using
280 // filenames it can't access in a future session restore.
281 if (!render_view_host_->CanAccessFilesOfPageState(
282 validated_params.page_state)) {
283 GetProcess()->ReceivedBadMessage();
284 return;
285 }
286
287 frame_tree_node()->navigator()->DidNavigate(this, validated_params);
288 }
289
190 void RenderFrameHostImpl::SwapOut() { 290 void RenderFrameHostImpl::SwapOut() {
191 if (render_view_host_->IsRenderViewLive()) { 291 if (render_view_host_->IsRenderViewLive()) {
192 Send(new FrameMsg_SwapOut(routing_id_)); 292 Send(new FrameMsg_SwapOut(routing_id_));
193 } else { 293 } else {
194 // Our RenderViewHost doesn't have a live renderer, so just skip the unload 294 // Our RenderViewHost doesn't have a live renderer, so just skip the unload
195 // event. 295 // event.
196 OnSwappedOut(true); 296 OnSwappedOut(true);
197 } 297 }
198 } 298 }
199 299
(...skipping 14 matching lines...) Expand all
214 // We don't validate |unfiltered_link_url| so that this field can be used 314 // We don't validate |unfiltered_link_url| so that this field can be used
215 // when users want to copy the original link URL. 315 // when users want to copy the original link URL.
216 process->FilterURL(true, &validated_params.link_url); 316 process->FilterURL(true, &validated_params.link_url);
217 process->FilterURL(true, &validated_params.src_url); 317 process->FilterURL(true, &validated_params.src_url);
218 process->FilterURL(false, &validated_params.page_url); 318 process->FilterURL(false, &validated_params.page_url);
219 process->FilterURL(true, &validated_params.frame_url); 319 process->FilterURL(true, &validated_params.frame_url);
220 320
221 delegate_->ShowContextMenu(this, validated_params); 321 delegate_->ShowContextMenu(this, validated_params);
222 } 322 }
223 323
324 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) {
325 // TODO(creis): We should also check for WebUI pages here. Also, when the
326 // out-of-process iframes implementation is ready, we should check for
327 // cross-site URLs that are not allowed to commit in this process.
328
329 // Give the client a chance to disallow URLs from committing.
330 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url);
331 }
332
224 } // namespace content 333 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698