OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/command_line.h" | 5 #include "base/command_line.h" |
6 #include "base/strings/stringprintf.h" | 6 #include "base/strings/stringprintf.h" |
7 #include "base/strings/utf_string_conversions.h" | |
8 #include "content/browser/frame_host/frame_tree.h" | |
9 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
10 #include "content/browser/renderer_host/render_view_host_impl.h" | |
11 #include "content/browser/web_contents/web_contents_impl.h" | |
12 #include "content/public/browser/navigation_entry.h" | 8 #include "content/public/browser/navigation_entry.h" |
13 #include "content/public/browser/notification_observer.h" | |
14 #include "content/public/browser/notification_service.h" | |
15 #include "content/public/browser/notification_types.h" | |
16 #include "content/public/browser/resource_dispatcher_host_delegate.h" | 9 #include "content/public/browser/resource_dispatcher_host_delegate.h" |
17 #include "content/public/browser/resource_throttle.h" | 10 #include "content/public/browser/resource_throttle.h" |
18 #include "content/public/browser/web_contents_observer.h" | 11 #include "content/public/browser/web_contents.h" |
19 #include "content/public/common/content_switches.h" | 12 #include "content/public/common/content_switches.h" |
20 #include "content/public/common/url_constants.h" | |
21 #include "content/public/test/browser_test_utils.h" | 13 #include "content/public/test/browser_test_utils.h" |
22 #include "content/public/test/test_navigation_observer.h" | 14 #include "content/public/test/test_navigation_observer.h" |
23 #include "content/public/test/test_utils.h" | |
24 #include "content/shell/browser/shell.h" | 15 #include "content/shell/browser/shell.h" |
25 #include "content/shell/browser/shell_content_browser_client.h" | 16 #include "content/shell/browser/shell_content_browser_client.h" |
26 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h" | 17 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h" |
27 #include "content/test/content_browser_test.h" | 18 #include "content/test/content_browser_test.h" |
28 #include "content/test/content_browser_test_utils.h" | 19 #include "content/test/content_browser_test_utils.h" |
29 #include "net/base/escape.h" | 20 #include "net/base/escape.h" |
30 #include "net/dns/mock_host_resolver.h" | 21 #include "net/dns/mock_host_resolver.h" |
31 #include "net/url_request/url_request.h" | 22 #include "net/url_request/url_request.h" |
32 #include "net/url_request/url_request_status.h" | 23 #include "net/url_request/url_request_status.h" |
| 24 #include "url/gurl.h" |
33 | 25 |
34 namespace content { | 26 namespace content { |
35 | 27 |
36 class SitePerProcessWebContentsObserver: public WebContentsObserver { | |
37 public: | |
38 explicit SitePerProcessWebContentsObserver(WebContents* web_contents) | |
39 : WebContentsObserver(web_contents), | |
40 navigation_succeeded_(false) {} | |
41 virtual ~SitePerProcessWebContentsObserver() {} | |
42 | |
43 virtual void DidStartProvisionalLoadForFrame( | |
44 int64 frame_id, | |
45 int64 parent_frame_id, | |
46 bool is_main_frame, | |
47 const GURL& validated_url, | |
48 bool is_error_page, | |
49 bool is_iframe_srcdoc, | |
50 RenderViewHost* render_view_host) OVERRIDE { | |
51 navigation_succeeded_ = false; | |
52 } | |
53 | |
54 virtual void DidFailProvisionalLoad( | |
55 int64 frame_id, | |
56 const base::string16& frame_unique_name, | |
57 bool is_main_frame, | |
58 const GURL& validated_url, | |
59 int error_code, | |
60 const base::string16& error_description, | |
61 RenderViewHost* render_view_host) OVERRIDE { | |
62 navigation_url_ = validated_url; | |
63 navigation_succeeded_ = false; | |
64 } | |
65 | |
66 virtual void DidCommitProvisionalLoadForFrame( | |
67 int64 frame_id, | |
68 const base::string16& frame_unique_name, | |
69 bool is_main_frame, | |
70 const GURL& url, | |
71 PageTransition transition_type, | |
72 RenderViewHost* render_view_host) OVERRIDE{ | |
73 navigation_url_ = url; | |
74 navigation_succeeded_ = true; | |
75 } | |
76 | |
77 const GURL& navigation_url() const { | |
78 return navigation_url_; | |
79 } | |
80 | |
81 int navigation_succeeded() const { return navigation_succeeded_; } | |
82 | |
83 private: | |
84 GURL navigation_url_; | |
85 bool navigation_succeeded_; | |
86 | |
87 DISALLOW_COPY_AND_ASSIGN(SitePerProcessWebContentsObserver); | |
88 }; | |
89 | |
90 class RedirectNotificationObserver : public NotificationObserver { | |
91 public: | |
92 // Register to listen for notifications of the given type from either a | |
93 // specific source, or from all sources if |source| is | |
94 // NotificationService::AllSources(). | |
95 RedirectNotificationObserver(int notification_type, | |
96 const NotificationSource& source); | |
97 virtual ~RedirectNotificationObserver(); | |
98 | |
99 // Wait until the specified notification occurs. If the notification was | |
100 // emitted between the construction of this object and this call then it | |
101 // returns immediately. | |
102 void Wait(); | |
103 | |
104 // Returns NotificationService::AllSources() if we haven't observed a | |
105 // notification yet. | |
106 const NotificationSource& source() const { | |
107 return source_; | |
108 } | |
109 | |
110 const NotificationDetails& details() const { | |
111 return details_; | |
112 } | |
113 | |
114 // NotificationObserver: | |
115 virtual void Observe(int type, | |
116 const NotificationSource& source, | |
117 const NotificationDetails& details) OVERRIDE; | |
118 | |
119 private: | |
120 bool seen_; | |
121 bool seen_twice_; | |
122 bool running_; | |
123 NotificationRegistrar registrar_; | |
124 | |
125 NotificationSource source_; | |
126 NotificationDetails details_; | |
127 scoped_refptr<MessageLoopRunner> message_loop_runner_; | |
128 | |
129 DISALLOW_COPY_AND_ASSIGN(RedirectNotificationObserver); | |
130 }; | |
131 | |
132 RedirectNotificationObserver::RedirectNotificationObserver( | |
133 int notification_type, | |
134 const NotificationSource& source) | |
135 : seen_(false), | |
136 running_(false), | |
137 source_(NotificationService::AllSources()) { | |
138 registrar_.Add(this, notification_type, source); | |
139 } | |
140 | |
141 RedirectNotificationObserver::~RedirectNotificationObserver() {} | |
142 | |
143 void RedirectNotificationObserver::Wait() { | |
144 if (seen_ && seen_twice_) | |
145 return; | |
146 | |
147 running_ = true; | |
148 message_loop_runner_ = new MessageLoopRunner; | |
149 message_loop_runner_->Run(); | |
150 EXPECT_TRUE(seen_); | |
151 } | |
152 | |
153 void RedirectNotificationObserver::Observe( | |
154 int type, | |
155 const NotificationSource& source, | |
156 const NotificationDetails& details) { | |
157 source_ = source; | |
158 details_ = details; | |
159 seen_twice_ = seen_; | |
160 seen_ = true; | |
161 if (!running_) | |
162 return; | |
163 | |
164 message_loop_runner_->Quit(); | |
165 running_ = false; | |
166 } | |
167 | |
168 // Tracks a single request for a specified URL, and allows waiting until the | 28 // Tracks a single request for a specified URL, and allows waiting until the |
169 // request is destroyed, and then inspecting whether it completed successfully. | 29 // request is destroyed, and then inspecting whether it completed successfully. |
170 class TrackingResourceDispatcherHostDelegate | 30 class TrackingResourceDispatcherHostDelegate |
171 : public ShellResourceDispatcherHostDelegate { | 31 : public ShellResourceDispatcherHostDelegate { |
172 public: | 32 public: |
173 TrackingResourceDispatcherHostDelegate() : throttle_created_(false) { | 33 TrackingResourceDispatcherHostDelegate() : throttle_created_(false) { |
174 } | 34 } |
175 | 35 |
176 virtual void RequestBeginning( | 36 virtual void RequestBeginning( |
177 net::URLRequest* request, | 37 net::URLRequest* request, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 params.should_replace_current_entry; | 162 params.should_replace_current_entry; |
303 load_url_params.is_renderer_initiated = true; | 163 load_url_params.is_renderer_initiated = true; |
304 source->GetController().LoadURLWithParams(load_url_params); | 164 source->GetController().LoadURLWithParams(load_url_params); |
305 return source; | 165 return source; |
306 } | 166 } |
307 | 167 |
308 private: | 168 private: |
309 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate); | 169 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate); |
310 }; | 170 }; |
311 | 171 |
312 class SitePerProcessBrowserTest : public ContentBrowserTest { | 172 class CrossSiteTransferTest : public ContentBrowserTest { |
313 public: | 173 public: |
314 SitePerProcessBrowserTest() : old_delegate_(NULL) { | 174 CrossSiteTransferTest() : old_delegate_(NULL) { |
315 } | 175 } |
316 | 176 |
317 // ContentBrowserTest implementation: | 177 // ContentBrowserTest implementation: |
318 virtual void SetUpOnMainThread() OVERRIDE { | 178 virtual void SetUpOnMainThread() OVERRIDE { |
319 BrowserThread::PostTask( | 179 BrowserThread::PostTask( |
320 BrowserThread::IO, FROM_HERE, | 180 BrowserThread::IO, FROM_HERE, |
321 base::Bind( | 181 base::Bind( |
322 &SitePerProcessBrowserTest::InjectResourceDisptcherHostDelegate, | 182 &CrossSiteTransferTest::InjectResourceDisptcherHostDelegate, |
323 base::Unretained(this))); | 183 base::Unretained(this))); |
324 } | 184 } |
325 | 185 |
326 virtual void TearDownOnMainThread() OVERRIDE { | 186 virtual void TearDownOnMainThread() OVERRIDE { |
327 BrowserThread::PostTask( | 187 BrowserThread::PostTask( |
328 BrowserThread::IO, FROM_HERE, | 188 BrowserThread::IO, FROM_HERE, |
329 base::Bind( | 189 base::Bind( |
330 &SitePerProcessBrowserTest::RestoreResourceDisptcherHostDelegate, | 190 &CrossSiteTransferTest::RestoreResourceDisptcherHostDelegate, |
331 base::Unretained(this))); | 191 base::Unretained(this))); |
332 } | 192 } |
333 | 193 |
334 protected: | 194 protected: |
335 // Start at a data URL so each extra navigation creates a navigation entry. | |
336 // (The first navigation will silently be classified as AUTO_SUBFRAME.) | |
337 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP. | |
338 void StartFrameAtDataURL() { | |
339 std::string data_url_script = | |
340 "var iframes = document.getElementById('test');iframes.src=" | |
341 "'data:text/html,dataurl';"; | |
342 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script)); | |
343 } | |
344 | |
345 bool NavigateIframeToURL(Shell* window, | |
346 const GURL& url, | |
347 std::string iframe_id) { | |
348 // TODO(creis): This should wait for LOAD_STOP, but cross-site subframe | |
349 // navigations generate extra DidStartLoading and DidStopLoading messages. | |
350 // Until we replace swappedout:// with frame proxies, we need to listen for | |
351 // something else. For now, we trigger NEW_SUBFRAME navigations and listen | |
352 // for commit. | |
353 std::string script = base::StringPrintf( | |
354 "setTimeout(\"" | |
355 "var iframes = document.getElementById('%s');iframes.src='%s';" | |
356 "\",0)", | |
357 iframe_id.c_str(), url.spec().c_str()); | |
358 WindowedNotificationObserver load_observer( | |
359 NOTIFICATION_NAV_ENTRY_COMMITTED, | |
360 Source<NavigationController>( | |
361 &window->web_contents()->GetController())); | |
362 bool result = ExecuteScript(window->web_contents(), script); | |
363 load_observer.Wait(); | |
364 return result; | |
365 } | |
366 | |
367 void NavigateToURLContentInitiated(Shell* window, | 195 void NavigateToURLContentInitiated(Shell* window, |
368 const GURL& url, | 196 const GURL& url, |
369 bool should_replace_current_entry, | 197 bool should_replace_current_entry, |
370 bool should_wait_for_navigation) { | 198 bool should_wait_for_navigation) { |
371 std::string script; | 199 std::string script; |
372 if (should_replace_current_entry) | 200 if (should_replace_current_entry) |
373 script = base::StringPrintf("location.replace('%s')", url.spec().c_str()); | 201 script = base::StringPrintf("location.replace('%s')", url.spec().c_str()); |
374 else | 202 else |
375 script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); | 203 script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); |
376 TestNavigationObserver load_observer(shell()->web_contents(), 1); | 204 TestNavigationObserver load_observer(shell()->web_contents(), 1); |
377 bool result = ExecuteScript(window->web_contents(), script); | 205 bool result = ExecuteScript(window->web_contents(), script); |
378 EXPECT_TRUE(result); | 206 EXPECT_TRUE(result); |
379 if (should_wait_for_navigation) | 207 if (should_wait_for_navigation) |
380 load_observer.Wait(); | 208 load_observer.Wait(); |
381 } | 209 } |
382 | 210 |
383 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | 211 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
| 212 // Use --site-per-process to force process swaps for cross-site transfers. |
384 command_line->AppendSwitch(switches::kSitePerProcess); | 213 command_line->AppendSwitch(switches::kSitePerProcess); |
385 | |
386 // TODO(creis): Remove this when GTK is no longer a supported platform. | |
387 command_line->AppendSwitch(switches::kForceCompositingMode); | |
388 } | 214 } |
389 | 215 |
390 void InjectResourceDisptcherHostDelegate() { | 216 void InjectResourceDisptcherHostDelegate() { |
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
392 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate(); | 218 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate(); |
393 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_); | 219 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_); |
394 } | 220 } |
395 | 221 |
396 void RestoreResourceDisptcherHostDelegate() { | 222 void RestoreResourceDisptcherHostDelegate() { |
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
398 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_); | 224 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_); |
399 old_delegate_ = NULL; | 225 old_delegate_ = NULL; |
400 } | 226 } |
401 | 227 |
402 TrackingResourceDispatcherHostDelegate& tracking_delegate() { | 228 TrackingResourceDispatcherHostDelegate& tracking_delegate() { |
403 return tracking_delegate_; | 229 return tracking_delegate_; |
404 } | 230 } |
405 | 231 |
406 private: | 232 private: |
407 TrackingResourceDispatcherHostDelegate tracking_delegate_; | 233 TrackingResourceDispatcherHostDelegate tracking_delegate_; |
408 ResourceDispatcherHostDelegate* old_delegate_; | 234 ResourceDispatcherHostDelegate* old_delegate_; |
409 }; | 235 }; |
410 | 236 |
411 // Ensure that we can complete a cross-process subframe navigation. | |
412 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { | |
413 host_resolver()->AddRule("*", "127.0.0.1"); | |
414 ASSERT_TRUE(test_server()->Start()); | |
415 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); | |
416 NavigateToURL(shell(), main_url); | |
417 | |
418 StartFrameAtDataURL(); | |
419 | |
420 SitePerProcessWebContentsObserver observer(shell()->web_contents()); | |
421 | |
422 // Load same-site page into iframe. | |
423 GURL http_url(test_server()->GetURL("files/title1.html")); | |
424 EXPECT_TRUE(NavigateIframeToURL(shell(), http_url, "test")); | |
425 EXPECT_EQ(http_url, observer.navigation_url()); | |
426 EXPECT_TRUE(observer.navigation_succeeded()); | |
427 | |
428 // These must stay in scope with replace_host. | |
429 GURL::Replacements replace_host; | |
430 std::string foo_com("foo.com"); | |
431 | |
432 // Load cross-site page into iframe. | |
433 GURL cross_site_url(test_server()->GetURL("files/title2.html")); | |
434 replace_host.SetHostStr(foo_com); | |
435 cross_site_url = cross_site_url.ReplaceComponents(replace_host); | |
436 EXPECT_TRUE(NavigateIframeToURL(shell(), cross_site_url, "test")); | |
437 EXPECT_EQ(cross_site_url, observer.navigation_url()); | |
438 EXPECT_TRUE(observer.navigation_succeeded()); | |
439 | |
440 // Ensure that we have created a new process for the subframe. | |
441 FrameTreeNode* root = | |
442 static_cast<WebContentsImpl*>(shell()->web_contents())-> | |
443 GetFrameTree()->root(); | |
444 ASSERT_EQ(1U, root->child_count()); | |
445 FrameTreeNode* child = root->child_at(0); | |
446 EXPECT_NE(shell()->web_contents()->GetRenderViewHost(), | |
447 child->current_frame_host()->render_view_host()); | |
448 EXPECT_NE(shell()->web_contents()->GetSiteInstance(), | |
449 child->current_frame_host()->render_view_host()->GetSiteInstance()); | |
450 EXPECT_NE(shell()->web_contents()->GetRenderProcessHost(), | |
451 child->current_frame_host()->GetProcess()); | |
452 } | |
453 | |
454 // Crash a subframe and ensures its children are cleared from the FrameTree. | |
455 // See http://crbug.com/338508. | |
456 // TODO(creis): Enable this on Android when we can kill the process there. | |
457 #if defined(OS_ANDROID) | |
458 #define MAYBE_CrashSubframe DISABLED_CrashSubframe | |
459 #else | |
460 #define MAYBE_CrashSubframe CrashSubframe | |
461 #endif | |
462 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CrashSubframe) { | |
463 host_resolver()->AddRule("*", "127.0.0.1"); | |
464 ASSERT_TRUE(test_server()->Start()); | |
465 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); | |
466 NavigateToURL(shell(), main_url); | |
467 | |
468 StartFrameAtDataURL(); | |
469 | |
470 // These must stay in scope with replace_host. | |
471 GURL::Replacements replace_host; | |
472 std::string foo_com("foo.com"); | |
473 | |
474 // Load cross-site page into iframe. | |
475 GURL cross_site_url(test_server()->GetURL("files/title2.html")); | |
476 replace_host.SetHostStr(foo_com); | |
477 cross_site_url = cross_site_url.ReplaceComponents(replace_host); | |
478 EXPECT_TRUE(NavigateIframeToURL(shell(), cross_site_url, "test")); | |
479 | |
480 // Check the subframe process. | |
481 FrameTreeNode* root = | |
482 static_cast<WebContentsImpl*>(shell()->web_contents())-> | |
483 GetFrameTree()->root(); | |
484 ASSERT_EQ(1U, root->child_count()); | |
485 FrameTreeNode* child = root->child_at(0); | |
486 EXPECT_EQ(main_url, root->current_url()); | |
487 EXPECT_EQ(cross_site_url, child->current_url()); | |
488 | |
489 // Crash the subframe process. | |
490 RenderProcessHost* root_process = root->current_frame_host()->GetProcess(); | |
491 RenderProcessHost* child_process = child->current_frame_host()->GetProcess(); | |
492 { | |
493 RenderProcessHostWatcher crash_observer( | |
494 child_process, | |
495 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); | |
496 base::KillProcess(child_process->GetHandle(), 0, false); | |
497 crash_observer.Wait(); | |
498 } | |
499 | |
500 // Ensure that the child frame still exists but has been cleared. | |
501 EXPECT_EQ(1U, root->child_count()); | |
502 EXPECT_EQ(main_url, root->current_url()); | |
503 EXPECT_EQ(GURL(), child->current_url()); | |
504 | |
505 // Now crash the top-level page to clear the child frame. | |
506 { | |
507 RenderProcessHostWatcher crash_observer( | |
508 root_process, | |
509 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); | |
510 base::KillProcess(root_process->GetHandle(), 0, false); | |
511 crash_observer.Wait(); | |
512 } | |
513 EXPECT_EQ(0U, root->child_count()); | |
514 EXPECT_EQ(GURL(), root->current_url()); | |
515 } | |
516 | |
517 // TODO(nasko): Disable this test until out-of-process iframes is ready and the | |
518 // security checks are back in place. | |
519 // TODO(creis): Replace SpawnedTestServer with host_resolver to get test to run | |
520 // on Android (http://crbug.com/187570). | |
521 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | |
522 DISABLED_CrossSiteIframeRedirectOnce) { | |
523 ASSERT_TRUE(test_server()->Start()); | |
524 net::SpawnedTestServer https_server( | |
525 net::SpawnedTestServer::TYPE_HTTPS, | |
526 net::SpawnedTestServer::kLocalhost, | |
527 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
528 ASSERT_TRUE(https_server.Start()); | |
529 | |
530 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); | |
531 GURL http_url(test_server()->GetURL("files/title1.html")); | |
532 GURL https_url(https_server.GetURL("files/title1.html")); | |
533 | |
534 NavigateToURL(shell(), main_url); | |
535 | |
536 SitePerProcessWebContentsObserver observer(shell()->web_contents()); | |
537 { | |
538 // Load cross-site client-redirect page into Iframe. | |
539 // Should be blocked. | |
540 GURL client_redirect_https_url(https_server.GetURL( | |
541 "client-redirect?files/title1.html")); | |
542 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
543 client_redirect_https_url, "test")); | |
544 // DidFailProvisionalLoad when navigating to client_redirect_https_url. | |
545 EXPECT_EQ(observer.navigation_url(), client_redirect_https_url); | |
546 EXPECT_FALSE(observer.navigation_succeeded()); | |
547 } | |
548 | |
549 { | |
550 // Load cross-site server-redirect page into Iframe, | |
551 // which redirects to same-site page. | |
552 GURL server_redirect_http_url(https_server.GetURL( | |
553 "server-redirect?" + http_url.spec())); | |
554 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
555 server_redirect_http_url, "test")); | |
556 EXPECT_EQ(observer.navigation_url(), http_url); | |
557 EXPECT_TRUE(observer.navigation_succeeded()); | |
558 } | |
559 | |
560 { | |
561 // Load cross-site server-redirect page into Iframe, | |
562 // which redirects to cross-site page. | |
563 GURL server_redirect_http_url(https_server.GetURL( | |
564 "server-redirect?files/title1.html")); | |
565 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
566 server_redirect_http_url, "test")); | |
567 // DidFailProvisionalLoad when navigating to https_url. | |
568 EXPECT_EQ(observer.navigation_url(), https_url); | |
569 EXPECT_FALSE(observer.navigation_succeeded()); | |
570 } | |
571 | |
572 { | |
573 // Load same-site server-redirect page into Iframe, | |
574 // which redirects to cross-site page. | |
575 GURL server_redirect_http_url(test_server()->GetURL( | |
576 "server-redirect?" + https_url.spec())); | |
577 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
578 server_redirect_http_url, "test")); | |
579 | |
580 EXPECT_EQ(observer.navigation_url(), https_url); | |
581 EXPECT_FALSE(observer.navigation_succeeded()); | |
582 } | |
583 | |
584 { | |
585 // Load same-site client-redirect page into Iframe, | |
586 // which redirects to cross-site page. | |
587 GURL client_redirect_http_url(test_server()->GetURL( | |
588 "client-redirect?" + https_url.spec())); | |
589 | |
590 RedirectNotificationObserver load_observer2( | |
591 NOTIFICATION_LOAD_STOP, | |
592 Source<NavigationController>( | |
593 &shell()->web_contents()->GetController())); | |
594 | |
595 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
596 client_redirect_http_url, "test")); | |
597 | |
598 // Same-site Client-Redirect Page should be loaded successfully. | |
599 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); | |
600 EXPECT_TRUE(observer.navigation_succeeded()); | |
601 | |
602 // Redirecting to Cross-site Page should be blocked. | |
603 load_observer2.Wait(); | |
604 EXPECT_EQ(observer.navigation_url(), https_url); | |
605 EXPECT_FALSE(observer.navigation_succeeded()); | |
606 } | |
607 | |
608 { | |
609 // Load same-site server-redirect page into Iframe, | |
610 // which redirects to same-site page. | |
611 GURL server_redirect_http_url(test_server()->GetURL( | |
612 "server-redirect?files/title1.html")); | |
613 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
614 server_redirect_http_url, "test")); | |
615 EXPECT_EQ(observer.navigation_url(), http_url); | |
616 EXPECT_TRUE(observer.navigation_succeeded()); | |
617 } | |
618 | |
619 { | |
620 // Load same-site client-redirect page into Iframe, | |
621 // which redirects to same-site page. | |
622 GURL client_redirect_http_url(test_server()->GetURL( | |
623 "client-redirect?" + http_url.spec())); | |
624 RedirectNotificationObserver load_observer2( | |
625 NOTIFICATION_LOAD_STOP, | |
626 Source<NavigationController>( | |
627 &shell()->web_contents()->GetController())); | |
628 | |
629 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
630 client_redirect_http_url, "test")); | |
631 | |
632 // Same-site Client-Redirect Page should be loaded successfully. | |
633 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); | |
634 EXPECT_TRUE(observer.navigation_succeeded()); | |
635 | |
636 // Redirecting to Same-site Page should be loaded successfully. | |
637 load_observer2.Wait(); | |
638 EXPECT_EQ(observer.navigation_url(), http_url); | |
639 EXPECT_TRUE(observer.navigation_succeeded()); | |
640 } | |
641 } | |
642 | |
643 // TODO(nasko): Disable this test until out-of-process iframes is ready and the | |
644 // security checks are back in place. | |
645 // TODO(creis): Replace SpawnedTestServer with host_resolver to get test to run | |
646 // on Android (http://crbug.com/187570). | |
647 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | |
648 DISABLED_CrossSiteIframeRedirectTwice) { | |
649 ASSERT_TRUE(test_server()->Start()); | |
650 net::SpawnedTestServer https_server( | |
651 net::SpawnedTestServer::TYPE_HTTPS, | |
652 net::SpawnedTestServer::kLocalhost, | |
653 base::FilePath(FILE_PATH_LITERAL("content/test/data"))); | |
654 ASSERT_TRUE(https_server.Start()); | |
655 | |
656 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); | |
657 GURL http_url(test_server()->GetURL("files/title1.html")); | |
658 GURL https_url(https_server.GetURL("files/title1.html")); | |
659 | |
660 NavigateToURL(shell(), main_url); | |
661 | |
662 SitePerProcessWebContentsObserver observer(shell()->web_contents()); | |
663 { | |
664 // Load client-redirect page pointing to a cross-site client-redirect page, | |
665 // which eventually redirects back to same-site page. | |
666 GURL client_redirect_https_url(https_server.GetURL( | |
667 "client-redirect?" + http_url.spec())); | |
668 GURL client_redirect_http_url(test_server()->GetURL( | |
669 "client-redirect?" + client_redirect_https_url.spec())); | |
670 | |
671 // We should wait until second client redirect get cancelled. | |
672 RedirectNotificationObserver load_observer2( | |
673 NOTIFICATION_LOAD_STOP, | |
674 Source<NavigationController>( | |
675 &shell()->web_contents()->GetController())); | |
676 | |
677 EXPECT_TRUE(NavigateIframeToURL(shell(), client_redirect_http_url, "test")); | |
678 | |
679 // DidFailProvisionalLoad when navigating to client_redirect_https_url. | |
680 load_observer2.Wait(); | |
681 EXPECT_EQ(observer.navigation_url(), client_redirect_https_url); | |
682 EXPECT_FALSE(observer.navigation_succeeded()); | |
683 } | |
684 | |
685 { | |
686 // Load server-redirect page pointing to a cross-site server-redirect page, | |
687 // which eventually redirect back to same-site page. | |
688 GURL server_redirect_https_url(https_server.GetURL( | |
689 "server-redirect?" + http_url.spec())); | |
690 GURL server_redirect_http_url(test_server()->GetURL( | |
691 "server-redirect?" + server_redirect_https_url.spec())); | |
692 EXPECT_TRUE(NavigateIframeToURL(shell(), | |
693 server_redirect_http_url, "test")); | |
694 EXPECT_EQ(observer.navigation_url(), http_url); | |
695 EXPECT_TRUE(observer.navigation_succeeded()); | |
696 } | |
697 | |
698 { | |
699 // Load server-redirect page pointing to a cross-site server-redirect page, | |
700 // which eventually redirects back to cross-site page. | |
701 GURL server_redirect_https_url(https_server.GetURL( | |
702 "server-redirect?" + https_url.spec())); | |
703 GURL server_redirect_http_url(test_server()->GetURL( | |
704 "server-redirect?" + server_redirect_https_url.spec())); | |
705 EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test")); | |
706 | |
707 // DidFailProvisionalLoad when navigating to https_url. | |
708 EXPECT_EQ(observer.navigation_url(), https_url); | |
709 EXPECT_FALSE(observer.navigation_succeeded()); | |
710 } | |
711 | |
712 { | |
713 // Load server-redirect page pointing to a cross-site client-redirect page, | |
714 // which eventually redirects back to same-site page. | |
715 GURL client_redirect_http_url(https_server.GetURL( | |
716 "client-redirect?" + http_url.spec())); | |
717 GURL server_redirect_http_url(test_server()->GetURL( | |
718 "server-redirect?" + client_redirect_http_url.spec())); | |
719 EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test")); | |
720 | |
721 // DidFailProvisionalLoad when navigating to client_redirect_http_url. | |
722 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); | |
723 EXPECT_FALSE(observer.navigation_succeeded()); | |
724 } | |
725 } | |
726 | |
727 // Tests that the |should_replace_current_entry| flag persists correctly across | 237 // Tests that the |should_replace_current_entry| flag persists correctly across |
728 // request transfers that began with a cross-process navigation. | 238 // request transfers that began with a cross-process navigation. |
729 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | 239 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, |
730 ReplaceEntryCrossProcessThenTransfer) { | 240 ReplaceEntryCrossProcessThenTransfer) { |
731 const NavigationController& controller = | 241 const NavigationController& controller = |
732 shell()->web_contents()->GetController(); | 242 shell()->web_contents()->GetController(); |
733 host_resolver()->AddRule("*", "127.0.0.1"); | 243 host_resolver()->AddRule("*", "127.0.0.1"); |
734 ASSERT_TRUE(test_server()->Start()); | 244 ASSERT_TRUE(test_server()->Start()); |
735 | 245 |
736 // These must all stay in scope with replace_host. | 246 // These must all stay in scope with replace_host. |
737 GURL::Replacements replace_host; | 247 GURL::Replacements replace_host; |
738 std::string a_com("A.com"); | 248 std::string a_com("A.com"); |
739 std::string b_com("B.com"); | 249 std::string b_com("B.com"); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); | 297 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); |
788 | 298 |
789 // Make sure the request succeeded. | 299 // Make sure the request succeeded. |
790 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); | 300 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); |
791 } | 301 } |
792 | 302 |
793 // Tests that the |should_replace_current_entry| flag persists correctly across | 303 // Tests that the |should_replace_current_entry| flag persists correctly across |
794 // request transfers that began with a content-initiated in-process | 304 // request transfers that began with a content-initiated in-process |
795 // navigation. This test is the same as the test above, except transfering from | 305 // navigation. This test is the same as the test above, except transfering from |
796 // in-process. | 306 // in-process. |
797 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | 307 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, |
798 ReplaceEntryInProcessThenTranfers) { | 308 ReplaceEntryInProcessThenTranfers) { |
799 const NavigationController& controller = | 309 const NavigationController& controller = |
800 shell()->web_contents()->GetController(); | 310 shell()->web_contents()->GetController(); |
801 ASSERT_TRUE(test_server()->Start()); | 311 ASSERT_TRUE(test_server()->Start()); |
802 | 312 |
803 // Navigate to a starting URL, so there is a history entry to replace. | 313 // Navigate to a starting URL, so there is a history entry to replace. |
804 GURL url = test_server()->GetURL("files/site_isolation/blank.html?1"); | 314 GURL url = test_server()->GetURL("files/site_isolation/blank.html?1"); |
805 NavigateToURL(shell(), url); | 315 NavigateToURL(shell(), url); |
806 | 316 |
807 // Force all future navigations to transfer. Note that this includes same-site | 317 // Force all future navigations to transfer. Note that this includes same-site |
(...skipping 21 matching lines...) Expand all Loading... |
829 // should not have replaced url3. | 339 // should not have replaced url3. |
830 EXPECT_TRUE(controller.GetPendingEntry() == NULL); | 340 EXPECT_TRUE(controller.GetPendingEntry() == NULL); |
831 EXPECT_EQ(2, controller.GetEntryCount()); | 341 EXPECT_EQ(2, controller.GetEntryCount()); |
832 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); | 342 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
833 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); | 343 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); |
834 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); | 344 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); |
835 } | 345 } |
836 | 346 |
837 // Tests that the |should_replace_current_entry| flag persists correctly across | 347 // Tests that the |should_replace_current_entry| flag persists correctly across |
838 // request transfers that cross processes twice from renderer policy. | 348 // request transfers that cross processes twice from renderer policy. |
839 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, | 349 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, |
840 ReplaceEntryCrossProcessTwice) { | 350 ReplaceEntryCrossProcessTwice) { |
841 const NavigationController& controller = | 351 const NavigationController& controller = |
842 shell()->web_contents()->GetController(); | 352 shell()->web_contents()->GetController(); |
843 host_resolver()->AddRule("*", "127.0.0.1"); | 353 host_resolver()->AddRule("*", "127.0.0.1"); |
844 ASSERT_TRUE(test_server()->Start()); | 354 ASSERT_TRUE(test_server()->Start()); |
845 | 355 |
846 // These must all stay in scope with replace_host. | 356 // These must all stay in scope with replace_host. |
847 GURL::Replacements replace_host; | 357 GURL::Replacements replace_host; |
848 std::string a_com("A.com"); | 358 std::string a_com("A.com"); |
849 std::string b_com("B.com"); | 359 std::string b_com("B.com"); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 // should not have replaced url3b. | 396 // should not have replaced url3b. |
887 EXPECT_TRUE(controller.GetPendingEntry() == NULL); | 397 EXPECT_TRUE(controller.GetPendingEntry() == NULL); |
888 EXPECT_EQ(2, controller.GetEntryCount()); | 398 EXPECT_EQ(2, controller.GetEntryCount()); |
889 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); | 399 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); |
890 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); | 400 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); |
891 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); | 401 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); |
892 } | 402 } |
893 | 403 |
894 // Tests that the request is destroyed when a cross process navigation is | 404 // Tests that the request is destroyed when a cross process navigation is |
895 // cancelled. | 405 // cancelled. |
896 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NoLeakOnCrossSiteCancel) { | 406 IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, NoLeakOnCrossSiteCancel) { |
897 const NavigationController& controller = | 407 const NavigationController& controller = |
898 shell()->web_contents()->GetController(); | 408 shell()->web_contents()->GetController(); |
899 host_resolver()->AddRule("*", "127.0.0.1"); | 409 host_resolver()->AddRule("*", "127.0.0.1"); |
900 ASSERT_TRUE(test_server()->Start()); | 410 ASSERT_TRUE(test_server()->Start()); |
901 | 411 |
902 // These must all stay in scope with replace_host. | 412 // These must all stay in scope with replace_host. |
903 GURL::Replacements replace_host; | 413 GURL::Replacements replace_host; |
904 std::string a_com("A.com"); | 414 std::string a_com("A.com"); |
905 std::string b_com("B.com"); | 415 std::string b_com("B.com"); |
906 | 416 |
(...skipping 28 matching lines...) Expand all Loading... |
935 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); | 445 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); |
936 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); | 446 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); |
937 | 447 |
938 // Make sure the request for url2 did not complete. | 448 // Make sure the request for url2 did not complete. |
939 EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); | 449 EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); |
940 | 450 |
941 shell()->web_contents()->SetDelegate(old_delegate); | 451 shell()->web_contents()->SetDelegate(old_delegate); |
942 } | 452 } |
943 | 453 |
944 } // namespace content | 454 } // namespace content |
OLD | NEW |