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

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: *Really* remove AbortTransfer 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 whether it completed successfully.
170 class TrackingResourceDispatcherHostDelegate
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 bool WaitForTrackedURLAndGetCompleted() {
218 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
219 run_loop_->Run();
220 run_loop_.reset();
221 return tracked_request_completed_;
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 // If the request is deleted without being cancelled, its status will
236 // indicate it succeeded, so have to check if the request is still pending
237 // as well.
238 tracker_->OnTrackedRequestDestroyed(
239 !request_->is_pending() && request_->status().is_success());
240 }
241
242 // ResourceThrottle implementation:
243 virtual const char* GetNameForLogging() const OVERRIDE {
244 return "TrackingThrottle";
245 }
246
247 private:
248 net::URLRequest* request_;
249 TrackingResourceDispatcherHostDelegate* tracker_;
250
251 DISALLOW_COPY_AND_ASSIGN(TrackingThrottle);
252 };
253
254 void SetTrackedURLOnIOThread(const GURL& tracked_url) {
255 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
256 throttle_created_ = false;
257 tracked_url_ = tracked_url;
258 }
259
260 void OnTrackedRequestDestroyed(bool completed) {
261 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
262 tracked_request_completed_ = completed;
263 tracked_url_ = GURL();
264
265 BrowserThread::PostTask(
266 BrowserThread::UI, FROM_HERE, run_loop_->QuitClosure());
267 }
268
269 // These live on the IO thread.
270 GURL tracked_url_;
271 bool throttle_created_;
272
273 // This is created and destroyed on the UI thread, but stopped on the IO
274 // thread.
275 scoped_ptr<base::RunLoop> run_loop_;
276
277 // Set on the IO thread while |run_loop_| is non-NULL, read on the UI thread
278 // after deleting run_loop_.
279 bool tracked_request_completed_;
280
281 DISALLOW_COPY_AND_ASSIGN(TrackingResourceDispatcherHostDelegate);
282 };
283
284 // WebContentsDelegate that fails to open a URL when there's a request that
285 // needs to be transferred between renderers.
286 class NoTransferRequestDelegate : public WebContentsDelegate {
287 public:
288 NoTransferRequestDelegate() {}
289
290 virtual WebContents* OpenURLFromTab(WebContents* source,
291 const OpenURLParams& params) OVERRIDE {
292 bool is_transfer =
293 (params.transferred_global_request_id != GlobalRequestID());
294 if (is_transfer)
295 return NULL;
296 NavigationController::LoadURLParams load_url_params(params.url);
297 load_url_params.referrer = params.referrer;
298 load_url_params.frame_tree_node_id = params.frame_tree_node_id;
299 load_url_params.transition_type = params.transition;
300 load_url_params.extra_headers = params.extra_headers;
301 load_url_params.should_replace_current_entry =
302 params.should_replace_current_entry;
303 load_url_params.is_renderer_initiated = true;
304 source->GetController().LoadURLWithParams(load_url_params);
305 return source;
306 }
307
308 private:
309 DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate);
310 };
311
162 class SitePerProcessBrowserTest : public ContentBrowserTest { 312 class SitePerProcessBrowserTest : public ContentBrowserTest {
313 public:
314 SitePerProcessBrowserTest() : old_delegate_(NULL) {
315 }
316
317 // ContentBrowserTest implementation:
318 virtual void SetUpOnMainThread() OVERRIDE {
319 BrowserThread::PostTask(
320 BrowserThread::IO, FROM_HERE,
321 base::Bind(
322 &SitePerProcessBrowserTest::InjectResourceDisptcherHostDelegate,
323 base::Unretained(this)));
324 }
325
326 virtual void TearDownOnMainThread() OVERRIDE {
327 BrowserThread::PostTask(
328 BrowserThread::IO, FROM_HERE,
329 base::Bind(
330 &SitePerProcessBrowserTest::RestoreResourceDisptcherHostDelegate,
331 base::Unretained(this)));
332 }
333
163 protected: 334 protected:
164 // Start at a data URL so each extra navigation creates a navigation entry. 335 // Start at a data URL so each extra navigation creates a navigation entry.
165 // (The first navigation will silently be classified as AUTO_SUBFRAME.) 336 // (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. 337 // TODO(creis): This won't be necessary when we can wait for LOAD_STOP.
167 void StartFrameAtDataURL() { 338 void StartFrameAtDataURL() {
168 std::string data_url_script = 339 std::string data_url_script =
169 "var iframes = document.getElementById('test');iframes.src=" 340 "var iframes = document.getElementById('test');iframes.src="
170 "'data:text/html,dataurl';"; 341 "'data:text/html,dataurl';";
171 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script)); 342 ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script));
172 } 343 }
(...skipping 15 matching lines...) Expand all
188 NOTIFICATION_NAV_ENTRY_COMMITTED, 359 NOTIFICATION_NAV_ENTRY_COMMITTED,
189 Source<NavigationController>( 360 Source<NavigationController>(
190 &window->web_contents()->GetController())); 361 &window->web_contents()->GetController()));
191 bool result = ExecuteScript(window->web_contents(), script); 362 bool result = ExecuteScript(window->web_contents(), script);
192 load_observer.Wait(); 363 load_observer.Wait();
193 return result; 364 return result;
194 } 365 }
195 366
196 void NavigateToURLContentInitiated(Shell* window, 367 void NavigateToURLContentInitiated(Shell* window,
197 const GURL& url, 368 const GURL& url,
198 bool should_replace_current_entry) { 369 bool should_replace_current_entry,
370 bool should_wait_for_navigation) {
199 std::string script; 371 std::string script;
200 if (should_replace_current_entry) 372 if (should_replace_current_entry)
201 script = base::StringPrintf("location.replace('%s')", url.spec().c_str()); 373 script = base::StringPrintf("location.replace('%s')", url.spec().c_str());
202 else 374 else
203 script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); 375 script = base::StringPrintf("location.href = '%s'", url.spec().c_str());
204 TestNavigationObserver load_observer(shell()->web_contents(), 1); 376 TestNavigationObserver load_observer(shell()->web_contents(), 1);
205 bool result = ExecuteScript(window->web_contents(), script); 377 bool result = ExecuteScript(window->web_contents(), script);
206 EXPECT_TRUE(result); 378 EXPECT_TRUE(result);
207 load_observer.Wait(); 379 if (should_wait_for_navigation)
380 load_observer.Wait();
208 } 381 }
209 382
210 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 383 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
211 command_line->AppendSwitch(switches::kSitePerProcess); 384 command_line->AppendSwitch(switches::kSitePerProcess);
212 385
213 // TODO(creis): Remove this when GTK is no longer a supported platform. 386 // TODO(creis): Remove this when GTK is no longer a supported platform.
214 command_line->AppendSwitch(switches::kForceCompositingMode); 387 command_line->AppendSwitch(switches::kForceCompositingMode);
215 } 388 }
389
390 void InjectResourceDisptcherHostDelegate() {
391 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
392 old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate();
393 ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_);
394 }
395
396 void RestoreResourceDisptcherHostDelegate() {
397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
398 ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_);
399 old_delegate_ = NULL;
400 }
401
402 TrackingResourceDispatcherHostDelegate& tracking_delegate() {
403 return tracking_delegate_;
404 }
405
406 private:
407 TrackingResourceDispatcherHostDelegate tracking_delegate_;
408 ResourceDispatcherHostDelegate* old_delegate_;
216 }; 409 };
217 410
218 // Ensure that we can complete a cross-process subframe navigation. 411 // Ensure that we can complete a cross-process subframe navigation.
219 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { 412 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
220 host_resolver()->AddRule("*", "127.0.0.1"); 413 host_resolver()->AddRule("*", "127.0.0.1");
221 ASSERT_TRUE(test_server()->Start()); 414 ASSERT_TRUE(test_server()->Start());
222 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); 415 GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
223 NavigateToURL(shell(), main_url); 416 NavigateToURL(shell(), main_url);
224 417
225 StartFrameAtDataURL(); 418 StartFrameAtDataURL();
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 // transfer). This test intentionally exercises that case. 684 // transfer). This test intentionally exercises that case.
492 ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 685 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
493 686
494 // Navigate to a page on A.com with entry replacement. This navigation is 687 // 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 688 // 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 689 // to a new process. It will then be transferred into yet another process due
497 // to the call above. 690 // to the call above.
498 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 691 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
499 replace_host.SetHostStr(a_com); 692 replace_host.SetHostStr(a_com);
500 url2 = url2.ReplaceComponents(replace_host); 693 url2 = url2.ReplaceComponents(replace_host);
501 NavigateToURLContentInitiated(shell(), url2, true); 694 // Used to make sure the request for url2 succeeds, and there was only one of
695 // them.
696 tracking_delegate().SetTrackedURL(url2);
697 NavigateToURLContentInitiated(shell(), url2, true, true);
502 698
503 // There should be one history entry. url2 should have replaced url1. 699 // There should be one history entry. url2 should have replaced url1.
504 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 700 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
505 EXPECT_EQ(1, controller.GetEntryCount()); 701 EXPECT_EQ(1, controller.GetEntryCount());
506 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 702 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
507 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 703 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
704 // Make sure the request succeeded.
705 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted());
508 706
509 // Now navigate as before to a page on B.com, but normally (without 707 // 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 708 // replacement). This will still perform a double process-swap as above, via
511 // OpenURL and then transfer. 709 // OpenURL and then transfer.
512 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); 710 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
513 replace_host.SetHostStr(b_com); 711 replace_host.SetHostStr(b_com);
514 url3 = url3.ReplaceComponents(replace_host); 712 url3 = url3.ReplaceComponents(replace_host);
515 NavigateToURLContentInitiated(shell(), url3, false); 713 // Used to make sure the request for url3 succeeds, and there was only one of
714 // them.
715 tracking_delegate().SetTrackedURL(url3);
716 NavigateToURLContentInitiated(shell(), url3, false, true);
516 717
517 // There should be two history entries. url2 should have replaced url1. url2 718 // There should be two history entries. url2 should have replaced url1. url2
518 // should not have replaced url3. 719 // should not have replaced url3.
519 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 720 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
520 EXPECT_EQ(2, controller.GetEntryCount()); 721 EXPECT_EQ(2, controller.GetEntryCount());
521 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 722 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
522 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 723 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
523 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); 724 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
725
726 // Make sure the request succeeded.
727 EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted());
524 } 728 }
525 729
526 // Tests that the |should_replace_current_entry| flag persists correctly across 730 // Tests that the |should_replace_current_entry| flag persists correctly across
527 // request transfers that began with a content-initiated in-process 731 // request transfers that began with a content-initiated in-process
528 // navigation. This test is the same as the test above, except transfering from 732 // navigation. This test is the same as the test above, except transfering from
529 // in-process. 733 // in-process.
530 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, 734 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
531 ReplaceEntryInProcessThenTranfers) { 735 ReplaceEntryInProcessThenTranfers) {
532 const NavigationController& controller = 736 const NavigationController& controller =
533 shell()->web_contents()->GetController(); 737 shell()->web_contents()->GetController();
534 ASSERT_TRUE(test_server()->Start()); 738 ASSERT_TRUE(test_server()->Start());
535 739
536 // Navigate to a starting URL, so there is a history entry to replace. 740 // 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"); 741 GURL url = test_server()->GetURL("files/site_isolation/blank.html?1");
538 NavigateToURL(shell(), url); 742 NavigateToURL(shell(), url);
539 743
540 // Force all future navigations to transfer. Note that this includes same-site 744 // 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 745 // 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 746 // transfer). All navigations in this test are same-site, so it only swaps
543 // processes via request transfer. 747 // processes via request transfer.
544 ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 748 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
545 749
546 // Navigate in-process with entry replacement. It will then be transferred 750 // Navigate in-process with entry replacement. It will then be transferred
547 // into a new one due to the call above. 751 // into a new one due to the call above.
548 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 752 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
549 NavigateToURLContentInitiated(shell(), url2, true); 753 NavigateToURLContentInitiated(shell(), url2, true, true);
550 754
551 // There should be one history entry. url2 should have replaced url1. 755 // There should be one history entry. url2 should have replaced url1.
552 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 756 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
553 EXPECT_EQ(1, controller.GetEntryCount()); 757 EXPECT_EQ(1, controller.GetEntryCount());
554 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 758 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
555 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 759 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
556 760
557 // Now navigate as before, but without replacement. 761 // Now navigate as before, but without replacement.
558 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); 762 GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
559 NavigateToURLContentInitiated(shell(), url3, false); 763 NavigateToURLContentInitiated(shell(), url3, false, true);
560 764
561 // There should be two history entries. url2 should have replaced url1. url2 765 // There should be two history entries. url2 should have replaced url1. url2
562 // should not have replaced url3. 766 // should not have replaced url3.
563 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 767 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
564 EXPECT_EQ(2, controller.GetEntryCount()); 768 EXPECT_EQ(2, controller.GetEntryCount());
565 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 769 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
566 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 770 EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
567 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); 771 EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
568 } 772 }
569 773
(...skipping 20 matching lines...) Expand all
590 // and second in response to the server redirect to B.com. The second swap is 794 // and second in response to the server redirect to B.com. The second swap is
591 // also renderer-initiated via OpenURL because decidePolicyForNavigation is 795 // also renderer-initiated via OpenURL because decidePolicyForNavigation is
592 // currently applied on redirects. 796 // currently applied on redirects.
593 GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2"); 797 GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2");
594 replace_host.SetHostStr(b_com); 798 replace_host.SetHostStr(b_com);
595 url2b = url2b.ReplaceComponents(replace_host); 799 url2b = url2b.ReplaceComponents(replace_host);
596 GURL url2a = test_server()->GetURL( 800 GURL url2a = test_server()->GetURL(
597 "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false)); 801 "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false));
598 replace_host.SetHostStr(a_com); 802 replace_host.SetHostStr(a_com);
599 url2a = url2a.ReplaceComponents(replace_host); 803 url2a = url2a.ReplaceComponents(replace_host);
600 NavigateToURLContentInitiated(shell(), url2a, true); 804 NavigateToURLContentInitiated(shell(), url2a, true, true);
601 805
602 // There should be one history entry. url2b should have replaced url1. 806 // There should be one history entry. url2b should have replaced url1.
603 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 807 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
604 EXPECT_EQ(1, controller.GetEntryCount()); 808 EXPECT_EQ(1, controller.GetEntryCount());
605 EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 809 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
606 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); 810 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
607 811
608 // Now repeat without replacement. 812 // Now repeat without replacement.
609 GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3"); 813 GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3");
610 replace_host.SetHostStr(b_com); 814 replace_host.SetHostStr(b_com);
611 url3b = url3b.ReplaceComponents(replace_host); 815 url3b = url3b.ReplaceComponents(replace_host);
612 GURL url3a = test_server()->GetURL( 816 GURL url3a = test_server()->GetURL(
613 "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false)); 817 "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false));
614 replace_host.SetHostStr(a_com); 818 replace_host.SetHostStr(a_com);
615 url3a = url3a.ReplaceComponents(replace_host); 819 url3a = url3a.ReplaceComponents(replace_host);
616 NavigateToURLContentInitiated(shell(), url3a, false); 820 NavigateToURLContentInitiated(shell(), url3a, false, true);
617 821
618 // There should be two history entries. url2b should have replaced url1. url2b 822 // There should be two history entries. url2b should have replaced url1. url2b
619 // should not have replaced url3b. 823 // should not have replaced url3b.
620 EXPECT_TRUE(controller.GetPendingEntry() == NULL); 824 EXPECT_TRUE(controller.GetPendingEntry() == NULL);
621 EXPECT_EQ(2, controller.GetEntryCount()); 825 EXPECT_EQ(2, controller.GetEntryCount());
622 EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 826 EXPECT_EQ(1, controller.GetCurrentEntryIndex());
623 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); 827 EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL());
624 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); 828 EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL());
625 } 829 }
626 830
831 // Tests that the request is destroyed when a cross process navigation is
832 // cancelled.
833 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NoLeakOnCrossSiteCancel) {
834 const NavigationController& controller =
835 shell()->web_contents()->GetController();
836 host_resolver()->AddRule("*", "127.0.0.1");
837 ASSERT_TRUE(test_server()->Start());
838
839 // These must all stay in scope with replace_host.
840 GURL::Replacements replace_host;
841 std::string a_com("A.com");
842 std::string b_com("B.com");
843
844 // Navigate to a starting URL, so there is a history entry to replace.
845 GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
846 NavigateToURL(shell(), url1);
847
848 // Force all future navigations to transfer.
849 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
850
851 NoTransferRequestDelegate no_transfer_request_delegate;
852 WebContentsDelegate* old_delegate = shell()->web_contents()->GetDelegate();
853 shell()->web_contents()->SetDelegate(&no_transfer_request_delegate);
854
855 // Navigate to a page on A.com with entry replacement. This navigation is
856 // cross-site, so the renderer will send it to the browser via OpenURL to give
857 // to a new process. It will then be transferred into yet another process due
858 // to the call above.
859 GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
860 replace_host.SetHostStr(a_com);
861 url2 = url2.ReplaceComponents(replace_host);
862 // Used to make sure the second request is cancelled, and there is only one
863 // request for url2.
864 tracking_delegate().SetTrackedURL(url2);
865
866 // Don't wait for the navigation to complete, since that never happens in
867 // this case.
868 NavigateToURLContentInitiated(shell(), url2, false, false);
869
870 // There should be one history entry, with url1.
871 EXPECT_EQ(1, controller.GetEntryCount());
872 EXPECT_EQ(0, controller.GetCurrentEntryIndex());
873 EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
874
875 // Make sure the request for url2 did not complete.
876 EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted());
877
878 shell()->web_contents()->SetDelegate(old_delegate);
879 }
880
627 } // namespace content 881 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_view_host_impl.cc ('k') | content/browser/web_contents/web_contents_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698