This source file includes following definitions.
- navigation_succeeded_
- DidStartProvisionalLoadForFrame
- DidFailProvisionalLoad
- DidCommitProvisionalLoadForFrame
- navigation_url
- navigation_succeeded
- source
- details
- source_
- Wait
- StartFrameAtDataURL
- NavigateIframeToURL
- SetUpCommandLine
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "url/gurl.h"
namespace content {
class SitePerProcessWebContentsObserver: public WebContentsObserver {
public:
explicit SitePerProcessWebContentsObserver(WebContents* web_contents)
: WebContentsObserver(web_contents),
navigation_succeeded_(false) {}
virtual ~SitePerProcessWebContentsObserver() {}
virtual void DidStartProvisionalLoadForFrame(
int64 frame_id,
int64 parent_frame_id,
bool is_main_frame,
const GURL& validated_url,
bool is_error_page,
bool is_iframe_srcdoc,
RenderViewHost* render_view_host) OVERRIDE {
navigation_succeeded_ = false;
}
virtual void DidFailProvisionalLoad(
int64 frame_id,
const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& validated_url,
int error_code,
const base::string16& error_description,
RenderViewHost* render_view_host) OVERRIDE {
navigation_url_ = validated_url;
navigation_succeeded_ = false;
}
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
RenderViewHost* render_view_host) OVERRIDE{
navigation_url_ = url;
navigation_succeeded_ = true;
}
const GURL& navigation_url() const {
return navigation_url_;
}
int navigation_succeeded() const { return navigation_succeeded_; }
private:
GURL navigation_url_;
bool navigation_succeeded_;
DISALLOW_COPY_AND_ASSIGN(SitePerProcessWebContentsObserver);
};
class RedirectNotificationObserver : public NotificationObserver {
public:
RedirectNotificationObserver(int notification_type,
const NotificationSource& source);
virtual ~RedirectNotificationObserver();
void Wait();
const NotificationSource& source() const {
return source_;
}
const NotificationDetails& details() const {
return details_;
}
virtual void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) OVERRIDE;
private:
bool seen_;
bool seen_twice_;
bool running_;
NotificationRegistrar registrar_;
NotificationSource source_;
NotificationDetails details_;
scoped_refptr<MessageLoopRunner> message_loop_runner_;
DISALLOW_COPY_AND_ASSIGN(RedirectNotificationObserver);
};
RedirectNotificationObserver::RedirectNotificationObserver(
int notification_type,
const NotificationSource& source)
: seen_(false),
running_(false),
source_(NotificationService::AllSources()) {
registrar_.Add(this, notification_type, source);
}
RedirectNotificationObserver::~RedirectNotificationObserver() {}
void RedirectNotificationObserver::Wait() {
if (seen_ && seen_twice_)
return;
running_ = true;
message_loop_runner_ = new MessageLoopRunner;
message_loop_runner_->Run();
EXPECT_TRUE(seen_);
}
void RedirectNotificationObserver::Observe(
int type,
const NotificationSource& source,
const NotificationDetails& details) {
source_ = source;
details_ = details;
seen_twice_ = seen_;
seen_ = true;
if (!running_)
return;
message_loop_runner_->Quit();
running_ = false;
}
class SitePerProcessBrowserTest : public ContentBrowserTest {
public:
SitePerProcessBrowserTest() {}
protected:
void StartFrameAtDataURL() {
std::string data_url_script =
"var iframes = document.getElementById('test');iframes.src="
"'data:text/html,dataurl';";
ASSERT_TRUE(ExecuteScript(shell()->web_contents(), data_url_script));
}
bool NavigateIframeToURL(Shell* window,
const GURL& url,
std::string iframe_id) {
std::string script = base::StringPrintf(
"setTimeout(\""
"var iframes = document.getElementById('%s');iframes.src='%s';"
"\",0)",
iframe_id.c_str(), url.spec().c_str());
WindowedNotificationObserver load_observer(
NOTIFICATION_NAV_ENTRY_COMMITTED,
Source<NavigationController>(
&window->web_contents()->GetController()));
bool result = ExecuteScript(window->web_contents(), script);
load_observer.Wait();
return result;
}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitch(switches::kSitePerProcess);
command_line->AppendSwitch(switches::kForceCompositingMode);
}
};
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) {
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
NavigateToURL(shell(), main_url);
StartFrameAtDataURL();
SitePerProcessWebContentsObserver observer(shell()->web_contents());
GURL http_url(test_server()->GetURL("files/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell(), http_url, "test"));
EXPECT_EQ(http_url, observer.navigation_url());
EXPECT_TRUE(observer.navigation_succeeded());
GURL::Replacements replace_host;
std::string foo_com("foo.com");
GURL cross_site_url(test_server()->GetURL("files/title2.html"));
replace_host.SetHostStr(foo_com);
cross_site_url = cross_site_url.ReplaceComponents(replace_host);
EXPECT_TRUE(NavigateIframeToURL(shell(), cross_site_url, "test"));
EXPECT_EQ(cross_site_url, observer.navigation_url());
EXPECT_TRUE(observer.navigation_succeeded());
FrameTreeNode* root =
static_cast<WebContentsImpl*>(shell()->web_contents())->
GetFrameTree()->root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_NE(shell()->web_contents()->GetRenderViewHost(),
child->current_frame_host()->render_view_host());
EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
child->current_frame_host()->render_view_host()->GetSiteInstance());
EXPECT_NE(shell()->web_contents()->GetRenderProcessHost(),
child->current_frame_host()->GetProcess());
}
#if defined(OS_ANDROID)
#define MAYBE_CrashSubframe DISABLED_CrashSubframe
#else
#define MAYBE_CrashSubframe CrashSubframe
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CrashSubframe) {
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
NavigateToURL(shell(), main_url);
StartFrameAtDataURL();
GURL::Replacements replace_host;
std::string foo_com("foo.com");
GURL cross_site_url(test_server()->GetURL("files/title2.html"));
replace_host.SetHostStr(foo_com);
cross_site_url = cross_site_url.ReplaceComponents(replace_host);
EXPECT_TRUE(NavigateIframeToURL(shell(), cross_site_url, "test"));
FrameTreeNode* root =
static_cast<WebContentsImpl*>(shell()->web_contents())->
GetFrameTree()->root();
ASSERT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
EXPECT_EQ(main_url, root->current_url());
EXPECT_EQ(cross_site_url, child->current_url());
RenderProcessHost* root_process = root->current_frame_host()->GetProcess();
RenderProcessHost* child_process = child->current_frame_host()->GetProcess();
{
RenderProcessHostWatcher crash_observer(
child_process,
RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
base::KillProcess(child_process->GetHandle(), 0, false);
crash_observer.Wait();
}
EXPECT_EQ(1U, root->child_count());
EXPECT_EQ(main_url, root->current_url());
EXPECT_EQ(GURL(), child->current_url());
{
RenderProcessHostWatcher crash_observer(
root_process,
RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
base::KillProcess(root_process->GetHandle(), 0, false);
crash_observer.Wait();
}
EXPECT_EQ(0U, root->child_count());
EXPECT_EQ(GURL(), root->current_url());
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DISABLED_CrossSiteIframeRedirectOnce) {
ASSERT_TRUE(test_server()->Start());
net::SpawnedTestServer https_server(
net::SpawnedTestServer::TYPE_HTTPS,
net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
GURL http_url(test_server()->GetURL("files/title1.html"));
GURL https_url(https_server.GetURL("files/title1.html"));
NavigateToURL(shell(), main_url);
SitePerProcessWebContentsObserver observer(shell()->web_contents());
{
GURL client_redirect_https_url(https_server.GetURL(
"client-redirect?files/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell(),
client_redirect_https_url, "test"));
EXPECT_EQ(observer.navigation_url(), client_redirect_https_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
{
GURL server_redirect_http_url(https_server.GetURL(
"server-redirect?" + http_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell(),
server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), http_url);
EXPECT_TRUE(observer.navigation_succeeded());
}
{
GURL server_redirect_http_url(https_server.GetURL(
"server-redirect?files/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell(),
server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), https_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
{
GURL server_redirect_http_url(test_server()->GetURL(
"server-redirect?" + https_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell(),
server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), https_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
{
GURL client_redirect_http_url(test_server()->GetURL(
"client-redirect?" + https_url.spec()));
RedirectNotificationObserver load_observer2(
NOTIFICATION_LOAD_STOP,
Source<NavigationController>(
&shell()->web_contents()->GetController()));
EXPECT_TRUE(NavigateIframeToURL(shell(),
client_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), client_redirect_http_url);
EXPECT_TRUE(observer.navigation_succeeded());
load_observer2.Wait();
EXPECT_EQ(observer.navigation_url(), https_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
{
GURL server_redirect_http_url(test_server()->GetURL(
"server-redirect?files/title1.html"));
EXPECT_TRUE(NavigateIframeToURL(shell(),
server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), http_url);
EXPECT_TRUE(observer.navigation_succeeded());
}
{
GURL client_redirect_http_url(test_server()->GetURL(
"client-redirect?" + http_url.spec()));
RedirectNotificationObserver load_observer2(
NOTIFICATION_LOAD_STOP,
Source<NavigationController>(
&shell()->web_contents()->GetController()));
EXPECT_TRUE(NavigateIframeToURL(shell(),
client_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), client_redirect_http_url);
EXPECT_TRUE(observer.navigation_succeeded());
load_observer2.Wait();
EXPECT_EQ(observer.navigation_url(), http_url);
EXPECT_TRUE(observer.navigation_succeeded());
}
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DISABLED_CrossSiteIframeRedirectTwice) {
ASSERT_TRUE(test_server()->Start());
net::SpawnedTestServer https_server(
net::SpawnedTestServer::TYPE_HTTPS,
net::SpawnedTestServer::kLocalhost,
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
GURL http_url(test_server()->GetURL("files/title1.html"));
GURL https_url(https_server.GetURL("files/title1.html"));
NavigateToURL(shell(), main_url);
SitePerProcessWebContentsObserver observer(shell()->web_contents());
{
GURL client_redirect_https_url(https_server.GetURL(
"client-redirect?" + http_url.spec()));
GURL client_redirect_http_url(test_server()->GetURL(
"client-redirect?" + client_redirect_https_url.spec()));
RedirectNotificationObserver load_observer2(
NOTIFICATION_LOAD_STOP,
Source<NavigationController>(
&shell()->web_contents()->GetController()));
EXPECT_TRUE(NavigateIframeToURL(shell(), client_redirect_http_url, "test"));
load_observer2.Wait();
EXPECT_EQ(observer.navigation_url(), client_redirect_https_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
{
GURL server_redirect_https_url(https_server.GetURL(
"server-redirect?" + http_url.spec()));
GURL server_redirect_http_url(test_server()->GetURL(
"server-redirect?" + server_redirect_https_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell(),
server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), http_url);
EXPECT_TRUE(observer.navigation_succeeded());
}
{
GURL server_redirect_https_url(https_server.GetURL(
"server-redirect?" + https_url.spec()));
GURL server_redirect_http_url(test_server()->GetURL(
"server-redirect?" + server_redirect_https_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), https_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
{
GURL client_redirect_http_url(https_server.GetURL(
"client-redirect?" + http_url.spec()));
GURL server_redirect_http_url(test_server()->GetURL(
"server-redirect?" + client_redirect_http_url.spec()));
EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test"));
EXPECT_EQ(observer.navigation_url(), client_redirect_http_url);
EXPECT_FALSE(observer.navigation_succeeded());
}
}
}