1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/command_line.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/stringprintf.h" 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/loader/resource_dispatcher_host_impl.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/resource_dispatcher_host_delegate.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/resource_throttle.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/web_contents.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/content_switches.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/test/browser_test_utils.h" 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h" 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test_utils.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/test/test_navigation_observer.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/shell/browser/shell.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/shell/browser/shell_content_browser_client.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/shell/browser/shell_resource_dispatcher_host_delegate.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/base/escape.h" 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/dns/mock_host_resolver.h" 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/url_request/url_request.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/url_request/url_request_status.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/gurl.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Tracks a single request for a specified URL, and allows waiting until the 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// request is destroyed, and then inspecting whether it completed successfully. 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class TrackingResourceDispatcherHostDelegate 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : public ShellResourceDispatcherHostDelegate { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TrackingResourceDispatcherHostDelegate() : throttle_created_(false) { 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void RequestBeginning( 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request, 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceContext* resource_context, 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AppCacheService* appcache_service, 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceType resource_type, 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScopedVector<ResourceThrottle>* throttles) OVERRIDE { 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ShellResourceDispatcherHostDelegate::RequestBeginning( 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) request, resource_context, appcache_service, resource_type, throttles); 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Expect only a single request for the tracked url. 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(throttle_created_); 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If this is a request for the tracked URL, add a throttle to track it. 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (request->url() == tracked_url_) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) throttles->push_back(new TrackingThrottle(request, this)); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Starts tracking a URL. The request for previously tracked URL, if any, 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // must have been made and deleted before calling this function. 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetTrackedURL(const GURL& tracked_url) { 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Should not currently be tracking any URL. 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_FALSE(run_loop_); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Create a RunLoop that will be stopped once the request for the tracked 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // URL has been destroyed, to allow tracking the URL while also waiting for 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // other events. 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) run_loop_.reset(new base::RunLoop()); 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::PostTask( 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind( 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &TrackingResourceDispatcherHostDelegate::SetTrackedURLOnIOThread, 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this), 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracked_url)); 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Waits until the tracked URL has been requests, and the request for it has 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // been destroyed. 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool WaitForTrackedURLAndGetCompleted() { 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) run_loop_->Run(); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) run_loop_.reset(); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return tracked_request_completed_; 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ResourceThrottle attached to request for the tracked URL. On destruction, 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // passes the final URLRequestStatus back to the delegate. 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) class TrackingThrottle : public ResourceThrottle { 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TrackingThrottle(net::URLRequest* request, 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TrackingResourceDispatcherHostDelegate* tracker) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : request_(request), tracker_(tracker) { 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~TrackingThrottle() { 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the request is deleted without being cancelled, its status will 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // indicate it succeeded, so have to check if the request is still pending 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // as well. 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracker_->OnTrackedRequestDestroyed( 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !request_->is_pending() && request_->status().is_success()); 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ResourceThrottle implementation: 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual const char* GetNameForLogging() const OVERRIDE { 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return "TrackingThrottle"; 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequest* request_; 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TrackingResourceDispatcherHostDelegate* tracker_; 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TrackingThrottle); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetTrackedURLOnIOThread(const GURL& tracked_url) { 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) throttle_created_ = false; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracked_url_ = tracked_url; 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void OnTrackedRequestDestroyed(bool completed) { 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracked_request_completed_ = completed; 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracked_url_ = GURL(); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::PostTask( 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::UI, FROM_HERE, run_loop_->QuitClosure()); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // These live on the IO thread. 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL tracked_url_; 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool throttle_created_; 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This is created and destroyed on the UI thread, but stopped on the IO 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // thread. 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::RunLoop> run_loop_; 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Set on the IO thread while |run_loop_| is non-NULL, read on the UI thread 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // after deleting run_loop_. 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool tracked_request_completed_; 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TrackingResourceDispatcherHostDelegate); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// WebContentsDelegate that fails to open a URL when there's a request that 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// needs to be transferred between renderers. 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class NoTransferRequestDelegate : public WebContentsDelegate { 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NoTransferRequestDelegate() {} 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual WebContents* OpenURLFromTab(WebContents* source, 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const OpenURLParams& params) OVERRIDE { 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_transfer = 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (params.transferred_global_request_id != GlobalRequestID()); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_transfer) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigationController::LoadURLParams load_url_params(params.url); 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_url_params.referrer = params.referrer; 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_url_params.frame_tree_node_id = params.frame_tree_node_id; 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_url_params.transition_type = params.transition; 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_url_params.extra_headers = params.extra_headers; 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_url_params.should_replace_current_entry = 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.should_replace_current_entry; 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_url_params.is_renderer_initiated = true; 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source->GetController().LoadURLWithParams(load_url_params); 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return source; 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NoTransferRequestDelegate); 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CrossSiteTransferTest : public ContentBrowserTest { 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CrossSiteTransferTest() : old_delegate_(NULL) { 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ContentBrowserTest implementation: 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void SetUpOnMainThread() OVERRIDE { 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::PostTask( 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind( 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &CrossSiteTransferTest::InjectResourceDisptcherHostDelegate, 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this))); 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void TearDownOnMainThread() OVERRIDE { 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::PostTask( 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind( 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &CrossSiteTransferTest::RestoreResourceDisptcherHostDelegate, 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this))); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected: 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void NavigateToURLContentInitiated(Shell* window, 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const GURL& url, 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool should_replace_current_entry, 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool should_wait_for_navigation) { 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string script; 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (should_replace_current_entry) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) script = base::StringPrintf("location.replace('%s')", url.spec().c_str()); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) script = base::StringPrintf("location.href = '%s'", url.spec().c_str()); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestNavigationObserver load_observer(shell()->web_contents(), 1); 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = ExecuteScript(window->web_contents(), script); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(result); 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (should_wait_for_navigation) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) load_observer.Wait(); 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Use --site-per-process to force process swaps for cross-site transfers. 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) command_line->AppendSwitch(switches::kSitePerProcess); 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void InjectResourceDisptcherHostDelegate() { 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) old_delegate_ = ResourceDispatcherHostImpl::Get()->delegate(); 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceDispatcherHostImpl::Get()->SetDelegate(&tracking_delegate_); 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void RestoreResourceDisptcherHostDelegate() { 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceDispatcherHostImpl::Get()->SetDelegate(old_delegate_); 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) old_delegate_ = NULL; 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TrackingResourceDispatcherHostDelegate& tracking_delegate() { 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return tracking_delegate_; 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TrackingResourceDispatcherHostDelegate tracking_delegate_; 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceDispatcherHostDelegate* old_delegate_; 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// The following tests crash in the ThreadSanitizer runtime, 235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// http://crbug.com/356758. 236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(THREAD_SANITIZER) 237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define MAYBE_ReplaceEntryCrossProcessThenTransfer \ 238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DISABLED_ReplaceEntryCrossProcessThenTransfer 239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define MAYBE_ReplaceEntryCrossProcessTwice \ 240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DISABLED_ReplaceEntryCrossProcessTwice 241effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#else 242effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define MAYBE_ReplaceEntryCrossProcessThenTransfer \ 243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReplaceEntryCrossProcessThenTransfer 244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#define MAYBE_ReplaceEntryCrossProcessTwice ReplaceEntryCrossProcessTwice 245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Tests that the |should_replace_current_entry| flag persists correctly across 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// request transfers that began with a cross-process navigation. 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, 249effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MAYBE_ReplaceEntryCrossProcessThenTransfer) { 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const NavigationController& controller = 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shell()->web_contents()->GetController(); 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host_resolver()->AddRule("*", "127.0.0.1"); 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // These must all stay in scope with replace_host. 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL::Replacements replace_host; 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string a_com("A.com"); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string b_com("B.com"); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a starting URL, so there is a history entry to replace. 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1"); 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURL(shell(), url1); 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Force all future navigations to transfer. Note that this includes same-site 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // navigiations which may cause double process swaps (via OpenURL and then via 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // transfer). This test intentionally exercises that case. 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a page on A.com with entry replacement. This navigation is 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // cross-site, so the renderer will send it to the browser via OpenURL to give 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to a new process. It will then be transferred into yet another process due 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to the call above. 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(a_com); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url2 = url2.ReplaceComponents(replace_host); 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Used to make sure the request for url2 succeeds, and there was only one of 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // them. 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracking_delegate().SetTrackedURL(url2); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url2, true, true); 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be one history entry. url2 should have replaced url1. 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(controller.GetPendingEntry() == NULL); 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetEntryCount()); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Make sure the request succeeded. 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Now navigate as before to a page on B.com, but normally (without 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // replacement). This will still perform a double process-swap as above, via 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // OpenURL and then transfer. 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(b_com); 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url3 = url3.ReplaceComponents(replace_host); 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Used to make sure the request for url3 succeeds, and there was only one of 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // them. 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracking_delegate().SetTrackedURL(url3); 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url3, false, true); 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be two history entries. url2 should have replaced url1. url2 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // should not have replaced url3. 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(controller.GetPendingEntry() == NULL); 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(2, controller.GetEntryCount()); 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Make sure the request succeeded. 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Tests that the |should_replace_current_entry| flag persists correctly across 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// request transfers that began with a content-initiated in-process 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// navigation. This test is the same as the test above, except transfering from 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// in-process. 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ReplaceEntryInProcessThenTranfers) { 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const NavigationController& controller = 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shell()->web_contents()->GetController(); 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a starting URL, so there is a history entry to replace. 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url = test_server()->GetURL("files/site_isolation/blank.html?1"); 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURL(shell(), url); 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Force all future navigations to transfer. Note that this includes same-site 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // navigiations which may cause double process swaps (via OpenURL and then via 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // transfer). All navigations in this test are same-site, so it only swaps 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // processes via request transfer. 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate in-process with entry replacement. It will then be transferred 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // into a new one due to the call above. 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url2, true, true); 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be one history entry. url2 should have replaced url1. 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(controller.GetPendingEntry() == NULL); 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetEntryCount()); 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Now navigate as before, but without replacement. 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3"); 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url3, false, true); 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be two history entries. url2 should have replaced url1. url2 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // should not have replaced url3. 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(controller.GetPendingEntry() == NULL); 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(2, controller.GetEntryCount()); 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL()); 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL()); 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Tests that the |should_replace_current_entry| flag persists correctly across 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// request transfers that cross processes twice from renderer policy. 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, 359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MAYBE_ReplaceEntryCrossProcessTwice) { 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const NavigationController& controller = 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shell()->web_contents()->GetController(); 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host_resolver()->AddRule("*", "127.0.0.1"); 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // These must all stay in scope with replace_host. 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL::Replacements replace_host; 367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string a_com("A.com"); 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string b_com("B.com"); 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a starting URL, so there is a history entry to replace. 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1"); 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURL(shell(), url1); 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a page on A.com which redirects to B.com with entry 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // replacement. This will switch processes via OpenURL twice. First to A.com, 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // and second in response to the server redirect to B.com. The second swap is 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // also renderer-initiated via OpenURL because decidePolicyForNavigation is 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // currently applied on redirects. 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url2b = test_server()->GetURL("files/site_isolation/blank.html?2"); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(b_com); 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url2b = url2b.ReplaceComponents(replace_host); 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url2a = test_server()->GetURL( 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "server-redirect?" + net::EscapeQueryParamValue(url2b.spec(), false)); 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(a_com); 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url2a = url2a.ReplaceComponents(replace_host); 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url2a, true, true); 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be one history entry. url2b should have replaced url1. 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(controller.GetPendingEntry() == NULL); 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetEntryCount()); 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Now repeat without replacement. 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url3b = test_server()->GetURL("files/site_isolation/blank.html?3"); 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(b_com); 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url3b = url3b.ReplaceComponents(replace_host); 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url3a = test_server()->GetURL( 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "server-redirect?" + net::EscapeQueryParamValue(url3b.spec(), false)); 400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(a_com); 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url3a = url3a.ReplaceComponents(replace_host); 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url3a, false, true); 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be two history entries. url2b should have replaced url1. url2b 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // should not have replaced url3b. 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(controller.GetPendingEntry() == NULL); 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(2, controller.GetEntryCount()); 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetCurrentEntryIndex()); 409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url2b, controller.GetEntryAtIndex(0)->GetURL()); 410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url3b, controller.GetEntryAtIndex(1)->GetURL()); 411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Tests that the request is destroyed when a cross process navigation is 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// cancelled. 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CrossSiteTransferTest, NoLeakOnCrossSiteCancel) { 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const NavigationController& controller = 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shell()->web_contents()->GetController(); 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host_resolver()->AddRule("*", "127.0.0.1"); 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // These must all stay in scope with replace_host. 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL::Replacements replace_host; 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string a_com("A.com"); 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string b_com("B.com"); 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a starting URL, so there is a history entry to replace. 427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1"); 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURL(shell(), url1); 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Force all future navigations to transfer. 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ShellContentBrowserClient::SetSwapProcessesForRedirect(true); 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NoTransferRequestDelegate no_transfer_request_delegate; 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WebContentsDelegate* old_delegate = shell()->web_contents()->GetDelegate(); 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shell()->web_contents()->SetDelegate(&no_transfer_request_delegate); 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Navigate to a page on A.com with entry replacement. This navigation is 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // cross-site, so the renderer will send it to the browser via OpenURL to give 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to a new process. It will then be transferred into yet another process due 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to the call above. 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2"); 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) replace_host.SetHostStr(a_com); 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url2 = url2.ReplaceComponents(replace_host); 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Used to make sure the second request is cancelled, and there is only one 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // request for url2. 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracking_delegate().SetTrackedURL(url2); 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Don't wait for the navigation to complete, since that never happens in 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // this case. 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NavigateToURLContentInitiated(shell(), url2, false, false); 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // There should be one history entry, with url1. 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, controller.GetEntryCount()); 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(0, controller.GetCurrentEntryIndex()); 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL()); 456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Make sure the request for url2 did not complete. 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(tracking_delegate().WaitForTrackedURLAndGetCompleted()); 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shell()->web_contents()->SetDelegate(old_delegate); 461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace content 464