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

Side by Side Diff: content/browser/site_per_process_browsertest.cc

Issue 143183009: When cross-site navigations are cancelled, delete the request being transferred (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: reupload, undo unneeded change 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 (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" 7 #include "base/strings/utf_string_conversions.h"
8 #include "content/browser/frame_host/frame_tree.h" 8 #include "content/browser/frame_host/frame_tree.h"
9 #include "content/browser/loader/resource_dispatcher_host_impl.h"
9 #include "content/browser/renderer_host/render_view_host_impl.h" 10 #include "content/browser/renderer_host/render_view_host_impl.h"
10 #include "content/browser/web_contents/web_contents_impl.h" 11 #include "content/browser/web_contents/web_contents_impl.h"
11 #include "content/public/browser/navigation_entry.h" 12 #include "content/public/browser/navigation_entry.h"
12 #include "content/public/browser/notification_observer.h" 13 #include "content/public/browser/notification_observer.h"
13 #include "content/public/browser/notification_service.h" 14 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_types.h" 15 #include "content/public/browser/notification_types.h"
16 #include "content/public/browser/resource_dispatcher_host_delegate.h"
17 #include "content/public/browser/resource_throttle.h"
15 #include "content/public/browser/web_contents_observer.h" 18 #include "content/public/browser/web_contents_observer.h"
16 #include "content/public/common/content_switches.h" 19 #include "content/public/common/content_switches.h"
17 #include "content/public/common/url_constants.h" 20 #include "content/public/common/url_constants.h"
18 #include "content/public/test/browser_test_utils.h" 21 #include "content/public/test/browser_test_utils.h"
19 #include "content/public/test/test_navigation_observer.h" 22 #include "content/public/test/test_navigation_observer.h"
20 #include "content/public/test/test_utils.h" 23 #include "content/public/test/test_utils.h"
21 #include "content/shell/browser/shell.h" 24 #include "content/shell/browser/shell.h"
22 #include "content/shell/browser/shell_content_browser_client.h" 25 #include "content/shell/browser/shell_content_browser_client.h"
26 #include "content/shell/browser/shell_resource_dispatcher_host_delegate.h"
23 #include "content/test/content_browser_test.h" 27 #include "content/test/content_browser_test.h"
24 #include "content/test/content_browser_test_utils.h" 28 #include "content/test/content_browser_test_utils.h"
25 #include "net/base/escape.h" 29 #include "net/base/escape.h"
26 #include "net/dns/mock_host_resolver.h" 30 #include "net/dns/mock_host_resolver.h"
31 #include "net/url_request/url_request.h"
32 #include "net/url_request/url_request_status.h"
27 33
28 namespace content { 34 namespace content {
29 35
30 class SitePerProcessWebContentsObserver: public WebContentsObserver { 36 class SitePerProcessWebContentsObserver: public WebContentsObserver {
31 public: 37 public:
32 explicit SitePerProcessWebContentsObserver(WebContents* web_contents) 38 explicit SitePerProcessWebContentsObserver(WebContents* web_contents)
33 : WebContentsObserver(web_contents), 39 : WebContentsObserver(web_contents),
34 navigation_succeeded_(false) {} 40 navigation_succeeded_(false) {}
35 virtual ~SitePerProcessWebContentsObserver() {} 41 virtual ~SitePerProcessWebContentsObserver() {}
36 42
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 details_ = details; 158 details_ = details;
153 seen_twice_ = seen_; 159 seen_twice_ = seen_;
154 seen_ = true; 160 seen_ = true;
155 if (!running_) 161 if (!running_)
156 return; 162 return;
157 163
158 message_loop_runner_->Quit(); 164 message_loop_runner_->Quit();
159 running_ = false; 165 running_ = false;
160 } 166 }
161 167
168 // Tracks a single request for a specified URL, and allows waiting until the
169 // request is destroyed, and then inspecting its final status.
170 class TrackingResourceDispatcherHostDelegate
Charlie Reis 2014/02/13 22:12:19 Thanks for figuring out how to test this. I'm get
mmenke 2014/02/14 16:30:02 This is pretty similar to how the network-related
171 : public ShellResourceDispatcherHostDelegate {
172 public:
173 TrackingResourceDispatcherHostDelegate() : throttle_created_(false) {
174 }
175
176 virtual void RequestBeginning(
177 net::URLRequest* request,
178 ResourceContext* resource_context,
179 appcache::AppCacheService* appcache_service,
180 ResourceType::Type resource_type,
181 int child_id,
182 int route_id,
183 ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
185 ShellResourceDispatcherHostDelegate::RequestBeginning(
186 request, resource_context, appcache_service, resource_type, child_id,
187 route_id, throttles);
188 // Expect only a single request for the tracked url.
189 ASSERT_FALSE(throttle_created_);
190 // If this is a request for the tracked URL, add a throttle to track it.
191 if (request->url() == tracked_url_)
192 throttles->push_back(new TrackingThrottle(request, this));
193 }
194
195 // Starts tracking a URL. The request for previously tracked URL, if any,
196 // must have been made and deleted before calling this function.
197 void SetTrackedURL(const GURL& tracked_url) {
198 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
199 // Should not currently be tracking any URL.
200 ASSERT_FALSE(run_loop_);
201
202 // Create a RunLoop that will be stopped once the request for the tracked
203 // URL has been destroyed, to allow tracking the URL while also waiting for
204 // other events.
205 run_loop_.reset(new base::RunLoop());
206
207 BrowserThread::PostTask(
208 BrowserThread::IO, FROM_HERE,
209 base::Bind(
210 &TrackingResourceDispatcherHostDelegate::SetTrackedURLOnIOThread,
211 base::Unretained(this),
212 tracked_url));
213 }
214
215 // Waits until the tracked URL has been requests, and the request for it has
216 // been destroyed.
217 net::URLRequestStatus WaitForTrackedURL() {
218 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
219 run_loop_->Run();
220 run_loop_.reset();
221 return tracked_request_status_;
222 }
223
224 private:
225 // ResourceThrottle attached to request for the tracked URL. On destruction,
226 // passes the final URLRequestStatus back to the delegate.
227 class TrackingThrottle : public ResourceThrottle {
228 public:
229 TrackingThrottle(net::URLRequest* request,
230 TrackingResourceDispatcherHostDelegate* tracker)
231 : request_(request), tracker_(tracker) {
232 }
233
234 virtual ~TrackingThrottle() {
235 tracker_->TrackedRequestCompleted(request_->status());
236 }
237
238 // ResourceThrottle implementation:
239 virtual const char* GetNameForLogging() const OVERRIDE {
240 return "TrackingThrottle";
241 }
242
243 private:
244 net::URLRequest* request_;
245 TrackingResourceDispatcherHostDelegate* tracker_;
246
247 DISALLOW_COPY_AND_ASSIGN(TrackingThrottle);
248 };
249
250 void SetTrackedURLOnIOThread(const GURL& tracked_url) {
251 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
252 throttle_created_ = false;
253 tracked_url_ = tracked_url;
254 }
255
256 void TrackedRequestCompleted(net::URLRequestStatus status) {
257 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
258 tracked_request_status_ = status;
259 tracked_url_ = GURL();
260
261 BrowserThread::PostTask(
262 BrowserThread::UI, FROM_HERE, run_loop_->QuitClosure());
263 }
264
265 // These live on the IO thread.
266 GURL tracked_url_;
267 bool throttle_created_;
268
269 // This is created and destroyed on the UI thread, but stopped on the IO
270 // thread.
271 scoped_ptr<base::RunLoop> run_loop_;
272
273 // Set on the IO thread while |run_loop_| is non-NULL, read on the UI thread
274 // after deleting run_loop_.
275 net::URLRequestStatus tracked_request_status_;
276
277 DISALLOW_COPY_AND_ASSIGN(TrackingResourceDispatcherHostDelegate);
278 };
279
280 // WebContentsDelegate that fails to open a URL when there's a request that
281 // needs to be transferred between renderers.
282 class NoTransferRequestDelegate : public WebContentsDelegate {
283 public:
284 NoTransferRequestDelegate() {}
285
286 virtual WebContents* OpenURLFromTab(WebContents* source,
287 const OpenURLParams& params) OVERRIDE {
288 bool is_transfer =
289 (params.transferred_global_request_id != GlobalRequestID());
290 if (is_transfer)
291 return NULL;
292 NavigationController::LoadURLParams load_url_params(params.url);
293 load_url_params.referrer = params.referrer;
294 load_url_params.frame_tree_node_id = params.frame_tree_node_id;
295 load_url_params.transition_type = params.transition;
296 load_url_params.extra_headers = params.extra_headers;
297 load_url_params.should_replace_current_entry =
298 params.should_replace_current_entry;
299 load_url_params.is_renderer_initiated = true;
300 source->GetController().LoadURLWithParams(load_url_params);
301 return source;
302 }
303
304 private:
305 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate);
306 };
307
162 class SitePerProcessBrowserTest : public ContentBrowserTest { 308 class SitePerProcessBrowserTest : public ContentBrowserTest {
309 public:
310 SitePerProcessBrowserTest() : old_delegate_(NULL) {
311 }
312
313 // ContentBrowserTest implementation:
314 virtual void SetUpOnMainThread() OVERRIDE {
315 BrowserThread::PostTask(
316 BrowserThread::IO, FROM_HERE,
317 base::Bind(
318 &SitePerProcessBrowserTest::InjectResourceDisptcherHostDelegate,
319 base::Unretained(this)));
320 }
321
322 virtual void TearDownOnMainThread() OVERRIDE {
323 BrowserThread::PostTask(
324 BrowserThread::IO, FROM_HERE,
325 base::Bind(
326 &SitePerProcessBrowserTest::RestoreResourceDisptcherHostDelegate,
327 base::Unretained(this)));
328 }
329
163 protected: 330 protected:
164 // Start at a data URL so each extra navigation creates a navigation entry. 331 // Start at a data URL so each extra navigation creates a navigation entry.
165 // (The first navigation will silently be classified as AUTO_SUBFRAME.) 332 // (The first navigation will silently be classified as AUTO_SUBFRAME.)
166 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP. 333 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP.
167 void StartFrameAtDataURL() { 334 void StartFrameAtDataURL() {
168 std::string data_url_script = 335 std::string data_url_script =
169 "var iframes = document.getElementById('test');iframes.src=" 336 "var iframes = document.getElementById('test');iframes.src="
170 "'data:text/html,dataurl';"; 337 "'data:text/html,dataurl';";
171 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script)); 338 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script));
172 } 339 }
(...skipping 15 matching lines...) Expand all
188 NOTIFICATION_NAV_ENTRY_COMMITTED, 355 NOTIFICATION_NAV_ENTRY_COMMITTED,
189 Source<NavigationController>( 356 Source<NavigationController>(
190 &window->web_contents()->GetController())); 357 &window->web_contents()->GetController()));
191 bool result = ExecuteScript(window->web_contents(), script); 358 bool result = ExecuteScript(window->web_contents(), script);
192 load_observer.Wait(); 359 load_observer.Wait();
193 return result; 360 return result;
194 } 361 }
195 362
196 void NavigateToURLContentInitiated(Shell* window, 363 void NavigateToURLContentInitiated(Shell* window,
197 const GURL& url, 364 const GURL& url,
198 bool should_replace_current_entry) { 365 bool should_replace_current_entry,
366 bool should_wait_for_navigation) {
199 std::string script; 367 std::string script;
200 if (should_replace_current_entry) 368 if (should_replace_current_entry)
201 script = base::StringPrintf("location.replace('%s')", url.spec().c_str()); 369 script = base::StringPrintf("location.replace('%s')", url.spec().c_str());
202 else 370 else
203 script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); 371 script = base::StringPrintf("location.href = '%s'", url.spec().c_str());
204 TestNavigationObserver load_observer(shell()->web_contents(), 1); 372 TestNavigationObserver load_observer(shell()->web_contents(), 1);
205 bool result = ExecuteScript(window->web_contents(), script); 373 bool result = ExecuteScript(window->web_contents(), script);
206 EXPECT_TRUE(result); 374 EXPECT_TRUE(result);
207 load_observer.Wait(); 375 if (should_wait_for_navigation)
376 load_observer.Wait();
208 } 377 }
209 378
210 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 379 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
211 command_line->AppendSwitch(switches::kSitePerProcess); 380 command_line->AppendSwitch(switches::kSitePerProcess);
212 381
213 // TODO(creis): Remove this when GTK is no longer a supported platform. 382 // TODO(creis): Remove this when GTK is no longer a supported platform.
214 command_line->AppendSwitch(switches::kForceCompositingMode); 383 command_line->AppendSwitch(switches::kForceCompositingMode);
215 } 384 }
385
386 void InjectResourceDisptcherHostDelegate() {
387 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
388 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate();
389 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_);
390 }
391
392 void RestoreResourceDisptcherHostDelegate() {
393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
394 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_);
395 old_delegate_ = NULL;
396 }
397
398 TrackingResourceDispatcherHostDelegate& tracking_delegate() {
399 return tracking_delegate_;
400 }
401
402 private:
403 TrackingResourceDispatcherHostDelegate tracking_delegate_;
404 ResourceDispatcherHostDelegate* old_delegate_;
216 }; 405 };
217 406
218 // Ensure that we can complete a cross-process subframe navigation. 407 // Ensure that we can complete a cross-process subframe navigation.
219 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { 408 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
220 host_resolver()->AddRule("*", "127.0.0.1"); 409 host_resolver()->AddRule("*", "127.0.0.1");
221 ASSERT_TRUE(test_server()->Start()); 410 ASSERT_TRUE(test_server()->Start());
222 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); 411 GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
223 NavigateToURL(shell(), main_url); 412 NavigateToURL(shell(), main_url);
224 413
225 StartFrameAtDataURL(); 414 StartFrameAtDataURL();
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 // transfer). This test intentionally exercises that case. 680 // transfer). This test intentionally exercises that case.
492 ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 681 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
493 682
494 // Navigate to a page on A.com with entry replacement. This navigation is 683 // Navigate to a page on A.com with entry replacement. This navigation is
495 // cross-site, so the renderer will send it to the browser via OpenURL to give 684 // cross-site, so the renderer will send it to the browser via OpenURL to give
496 // to a new process. It will then be transferred into yet another process due 685 // to a new process. It will then be transferred into yet another process due
497 // to the call above. 686 // to the call above.
498 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 687 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
499 replace_host.SetHostStr(a_com); 688 replace_host.SetHostStr(a_com);
500 url2 = url2.ReplaceComponents(replace_host); 689 url2 = url2.ReplaceComponents(replace_host);
501 NavigateToURLContentInitiated(shell(), url2, true); 690 // Used to make sure the request for url2 succeeds, and there was only one of
691 // them.
692 tracking_delegate().SetTrackedURL(url2);
693 NavigateToURLContentInitiated(shell(), url2, true, true);
502 694
503 // There should be one history entry. url2 should have replaced url1. 695 // There should be one history entry. url2 should have replaced url1.
504 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 696 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
505 EXPECT_EQ(1, controller.GetEntryCount()); 697 EXPECT_EQ(1, controller.GetEntryCount());
506 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 698 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
507 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 699 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
700 // Make sure the request succeeded.
701 net::URLRequestStatus status = tracking_delegate().WaitForTrackedURL();
702 EXPECT_TRUE(status.is_success());
508 703
509 // Now navigate as before to a page on B.com, but normally (without 704 // Now navigate as before to a page on B.com, but normally (without
510 // replacement). This will still perform a double process-swap as above, via 705 // replacement). This will still perform a double process-swap as above, via
511 // OpenURL and then transfer. 706 // OpenURL and then transfer.
512 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); 707 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
513 replace_host.SetHostStr(b_com); 708 replace_host.SetHostStr(b_com);
514 url3 = url3.ReplaceComponents(replace_host); 709 url3 = url3.ReplaceComponents(replace_host);
515 NavigateToURLContentInitiated(shell(), url3, false); 710 // Used to make sure the request for url3 succeeds, and there was only one of
711 // them.
712 tracking_delegate().SetTrackedURL(url3);
713 NavigateToURLContentInitiated(shell(), url3, false, true);
516 714
517 // There should be two history entries. url2 should have replaced url1. url2 715 // There should be two history entries. url2 should have replaced url1. url2
518 // should not have replaced url3. 716 // should not have replaced url3.
519 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 717 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
520 EXPECT_EQ(2, controller.GetEntryCount()); 718 EXPECT_EQ(2, controller.GetEntryCount());
521 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 719 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
522 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 720 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
523 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); 721 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
722
723 // Make sure the request succeeded.
724 status = tracking_delegate().WaitForTrackedURL();
725 EXPECT_TRUE(status.is_success());
524 } 726 }
525 727
526 // Tests that the |should_replace_current_entry| flag persists correctly across 728 // Tests that the |should_replace_current_entry| flag persists correctly across
527 // request transfers that began with a content-initiated in-process 729 // request transfers that began with a content-initiated in-process
528 // navigation. This test is the same as the test above, except transfering from 730 // navigation. This test is the same as the test above, except transfering from
529 // in-process. 731 // in-process.
530 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, 732 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
531 ReplaceEntryInProcessThenTranfers) { 733 ReplaceEntryInProcessThenTranfers) {
532 const NavigationController& controller = 734 const NavigationController& controller =
533 shell()->web_contents()->GetController(); 735 shell()->web_contents()->GetController();
534 ASSERT_TRUE(test_server()->Start()); 736 ASSERT_TRUE(test_server()->Start());
535 737
536 // Navigate to a starting URL, so there is a history entry to replace. 738 // Navigate to a starting URL, so there is a history entry to replace.
537 GURL url = test_server()->GetURL("files/site_isolation/blank.html?1"); 739 GURL url = test_server()->GetURL("files/site_isolation/blank.html?1");
538 NavigateToURL(shell(), url); 740 NavigateToURL(shell(), url);
539 741
540 // Force all future navigations to transfer. Note that this includes same-site 742 // Force all future navigations to transfer. Note that this includes same-site
541 // navigiations which may cause double process swaps (via OpenURL and then via 743 // navigiations which may cause double process swaps (via OpenURL and then via
542 // transfer). All navigations in this test are same-site, so it only swaps 744 // transfer). All navigations in this test are same-site, so it only swaps
543 // processes via request transfer. 745 // processes via request transfer.
544 ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 746 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
545 747
546 // Navigate in-process with entry replacement. It will then be transferred 748 // Navigate in-process with entry replacement. It will then be transferred
547 // into a new one due to the call above. 749 // into a new one due to the call above.
548 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 750 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
549 NavigateToURLContentInitiated(shell(), url2, true); 751 NavigateToURLContentInitiated(shell(), url2, true, true);
550 752
551 // There should be one history entry. url2 should have replaced url1. 753 // There should be one history entry. url2 should have replaced url1.
552 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 754 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
553 EXPECT_EQ(1, controller.GetEntryCount()); 755 EXPECT_EQ(1, controller.GetEntryCount());
554 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 756 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
555 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 757 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
556 758
557 // Now navigate as before, but without replacement. 759 // Now navigate as before, but without replacement.
558 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); 760 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
559 NavigateToURLContentInitiated(shell(), url3, false); 761 NavigateToURLContentInitiated(shell(), url3, false, true);
560 762
561 // There should be two history entries. url2 should have replaced url1. url2 763 // There should be two history entries. url2 should have replaced url1. url2
562 // should not have replaced url3. 764 // should not have replaced url3.
563 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 765 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
564 EXPECT_EQ(2, controller.GetEntryCount()); 766 EXPECT_EQ(2, controller.GetEntryCount());
565 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 767 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
566 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 768 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
567 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); 769 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
568 } 770 }
569 771
(...skipping 20 matching lines...) Expand all
590 // and second in response to the server redirect to B.com. The second swap is 792 // and second in response to the server redirect to B.com. The second swap is
591 // also renderer-initiated via OpenURL because decidePolicyForNavigation is 793 // also renderer-initiated via OpenURL because decidePolicyForNavigation is
592 // currently applied on redirects. 794 // currently applied on redirects.
593 GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2"); 795 GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2");
594 replace_host.SetHostStr(b_com); 796 replace_host.SetHostStr(b_com);
595 url2b = url2b.ReplaceComponents(replace_host); 797 url2b = url2b.ReplaceComponents(replace_host);
596 GURL url2a = test_server()->GetURL( 798 GURL url2a = test_server()->GetURL(
597 "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false)); 799 "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false));
598 replace_host.SetHostStr(a_com); 800 replace_host.SetHostStr(a_com);
599 url2a = url2a.ReplaceComponents(replace_host); 801 url2a = url2a.ReplaceComponents(replace_host);
600 NavigateToURLContentInitiated(shell(), url2a, true); 802 NavigateToURLContentInitiated(shell(), url2a, true, true);
601 803
602 // There should be one history entry. url2b should have replaced url1. 804 // There should be one history entry. url2b should have replaced url1.
603 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 805 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
604 EXPECT_EQ(1, controller.GetEntryCount()); 806 EXPECT_EQ(1, controller.GetEntryCount());
605 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 807 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
606 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); 808 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
607 809
608 // Now repeat without replacement. 810 // Now repeat without replacement.
609 GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3"); 811 GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3");
610 replace_host.SetHostStr(b_com); 812 replace_host.SetHostStr(b_com);
611 url3b = url3b.ReplaceComponents(replace_host); 813 url3b = url3b.ReplaceComponents(replace_host);
612 GURL url3a = test_server()->GetURL( 814 GURL url3a = test_server()->GetURL(
613 "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false)); 815 "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false));
614 replace_host.SetHostStr(a_com); 816 replace_host.SetHostStr(a_com);
615 url3a = url3a.ReplaceComponents(replace_host); 817 url3a = url3a.ReplaceComponents(replace_host);
616 NavigateToURLContentInitiated(shell(), url3a, false); 818 NavigateToURLContentInitiated(shell(), url3a, false, true);
617 819
618 // There should be two history entries. url2b should have replaced url1. url2b 820 // There should be two history entries. url2b should have replaced url1. url2b
619 // should not have replaced url3b. 821 // should not have replaced url3b.
620 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 822 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
621 EXPECT_EQ(2, controller.GetEntryCount()); 823 EXPECT_EQ(2, controller.GetEntryCount());
622 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 824 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
623 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); 825 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
624 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); 826 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL());
625 } 827 }
626 828
829 // Tests that the request is destroyed when a cross process navigation is
830 // cancelled.
831 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NoLeakOnCrossSiteCancel) {
832 const NavigationController& controller =
833 shell()->web_contents()->GetController();
834 host_resolver()->AddRule("*", "127.0.0.1");
835 ASSERT_TRUE(test_server()->Start());
836
837 // These must all stay in scope with replace_host.
838 GURL::Replacements replace_host;
839 std::string a_com("A.com");
840 std::string b_com("B.com");
841
842 // Navigate to a starting URL, so there is a history entry to replace.
843 GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
844 NavigateToURL(shell(), url1);
845
846 // Force all future navigations to transfer.
847 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
848
849 NoTransferRequestDelegate no_transfer_request_delegate;
850 WebContentsDelegate* old_delegate = shell()->web_contents()->GetDelegate();
851 shell()->web_contents()->SetDelegate(&no_transfer_request_delegate);
852
853 // Navigate to a page on A.com with entry replacement. This navigation is
854 // cross-site, so the renderer will send it to the browser via OpenURL to give
855 // to a new process. It will then be transferred into yet another process due
856 // to the call above.
857 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
858 replace_host.SetHostStr(a_com);
859 url2 = url2.ReplaceComponents(replace_host);
860 // Used to make sure the second request is cancelled, and there is only one
861 // request for url2.
862 tracking_delegate().SetTrackedURL(url2);
863
864 // Don't want for the navigation to complete, since that never happens in
Charlie Reis 2014/02/13 22:12:19 nit: wait
mmenke 2014/02/14 16:30:02 Done.
865 // this case.
866 NavigateToURLContentInitiated(shell(), url2, false, false);
867
868 // There should be one history entry, with url1.
869 EXPECT_EQ(1, controller.GetEntryCount());
870 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
871 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
872
873 // Make sure the request for url2 was cancelled.
874 net::URLRequestStatus status = tracking_delegate().WaitForTrackedURL();
875 EXPECT_FALSE(status.is_success());
876 EXPECT_EQ(net::URLRequestStatus::CANCELED, status.status());
877
878 shell()->web_contents()->SetDelegate(old_delegate);
879 }
880
627 } // namespace content 881 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698