OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/command_line.h" |
| 6 #include "base/stringprintf.h" |
| 7 #include "base/utf_string_conversions.h" |
| 8 #include "content/browser/web_contents/web_contents_impl.h" |
| 9 #include "content/public/browser/notification_observer.h" |
| 10 #include "content/public/browser/notification_service.h" |
| 11 #include "content/public/browser/notification_types.h" |
| 12 #include "content/public/browser/web_contents_observer.h" |
| 13 #include "content/public/common/content_switches.h" |
| 14 #include "content/public/test/browser_test_utils.h" |
| 15 #include "content/public/test/test_utils.h" |
| 16 #include "content/shell/shell.h" |
| 17 #include "content/test/content_browser_test.h" |
| 18 #include "content/test/content_browser_test_utils.h" |
| 19 |
| 20 namespace content { |
| 21 |
| 22 class SitePerProcessWebContentsObserver: public WebContentsObserver { |
| 23 public: |
| 24 explicit SitePerProcessWebContentsObserver(WebContents* web_contents) |
| 25 : WebContentsObserver(web_contents), |
| 26 navigation_succeeded_(true) {} |
| 27 virtual ~SitePerProcessWebContentsObserver() {} |
| 28 |
| 29 virtual void DidFailProvisionalLoad( |
| 30 int64 frame_id, |
| 31 bool is_main_frame, |
| 32 const GURL& validated_url, |
| 33 int error_code, |
| 34 const string16& error_description, |
| 35 RenderViewHost* render_view_host) OVERRIDE { |
| 36 navigation_url_ = validated_url; |
| 37 navigation_succeeded_ = false; |
| 38 } |
| 39 |
| 40 virtual void DidCommitProvisionalLoadForFrame( |
| 41 int64 frame_id, |
| 42 bool is_main_frame, |
| 43 const GURL& url, |
| 44 PageTransition transition_type, |
| 45 RenderViewHost* render_view_host) OVERRIDE{ |
| 46 navigation_url_ = url; |
| 47 navigation_succeeded_ = true; |
| 48 } |
| 49 |
| 50 const GURL& navigation_url() const { |
| 51 return navigation_url_; |
| 52 } |
| 53 |
| 54 int navigation_succeeded() const { return navigation_succeeded_; } |
| 55 |
| 56 private: |
| 57 GURL navigation_url_; |
| 58 bool navigation_succeeded_; |
| 59 |
| 60 DISALLOW_COPY_AND_ASSIGN(SitePerProcessWebContentsObserver); |
| 61 }; |
| 62 |
| 63 class RedirectNotificationObserver : public NotificationObserver { |
| 64 public: |
| 65 // Register to listen for notifications of the given type from either a |
| 66 // specific source, or from all sources if |source| is |
| 67 // NotificationService::AllSources(). |
| 68 RedirectNotificationObserver(int notification_type, |
| 69 const NotificationSource& source); |
| 70 virtual ~RedirectNotificationObserver(); |
| 71 |
| 72 // Wait until the specified notification occurs. If the notification was |
| 73 // emitted between the construction of this object and this call then it |
| 74 // returns immediately. |
| 75 void Wait(); |
| 76 |
| 77 // Returns NotificationService::AllSources() if we haven't observed a |
| 78 // notification yet. |
| 79 const NotificationSource& source() const { |
| 80 return source_; |
| 81 } |
| 82 |
| 83 const NotificationDetails& details() const { |
| 84 return details_; |
| 85 } |
| 86 |
| 87 // NotificationObserver: |
| 88 virtual void Observe(int type, |
| 89 const NotificationSource& source, |
| 90 const NotificationDetails& details) OVERRIDE; |
| 91 |
| 92 private: |
| 93 bool seen_; |
| 94 bool seen_twice_; |
| 95 bool running_; |
| 96 NotificationRegistrar registrar_; |
| 97 |
| 98 NotificationSource source_; |
| 99 NotificationDetails details_; |
| 100 scoped_refptr<MessageLoopRunner> message_loop_runner_; |
| 101 |
| 102 DISALLOW_COPY_AND_ASSIGN(RedirectNotificationObserver); |
| 103 }; |
| 104 |
| 105 RedirectNotificationObserver::RedirectNotificationObserver( |
| 106 int notification_type, |
| 107 const NotificationSource& source) |
| 108 : seen_(false), |
| 109 running_(false), |
| 110 source_(NotificationService::AllSources()) { |
| 111 registrar_.Add(this, notification_type, source); |
| 112 } |
| 113 |
| 114 RedirectNotificationObserver::~RedirectNotificationObserver() {} |
| 115 |
| 116 void RedirectNotificationObserver::Wait() { |
| 117 if (seen_ && seen_twice_) |
| 118 return; |
| 119 |
| 120 running_ = true; |
| 121 message_loop_runner_ = new MessageLoopRunner; |
| 122 message_loop_runner_->Run(); |
| 123 EXPECT_TRUE(seen_); |
| 124 } |
| 125 |
| 126 void RedirectNotificationObserver::Observe( |
| 127 int type, |
| 128 const NotificationSource& source, |
| 129 const NotificationDetails& details) { |
| 130 source_ = source; |
| 131 details_ = details; |
| 132 seen_twice_ = seen_; |
| 133 seen_ = true; |
| 134 if (!running_) |
| 135 return; |
| 136 |
| 137 message_loop_runner_->Quit(); |
| 138 running_ = false; |
| 139 } |
| 140 |
| 141 class SitePerProcessBrowserTest : public ContentBrowserTest { |
| 142 public: |
| 143 SitePerProcessBrowserTest() {} |
| 144 |
| 145 bool NavigateIframeToURL(Shell* window, |
| 146 const GURL& url, |
| 147 std::string iframe_id) { |
| 148 std::string script = base::StringPrintf( |
| 149 "var iframes = document.getElementById('%s');iframes.src='%s';", |
| 150 iframe_id.c_str(), url.spec().c_str()); |
| 151 WindowedNotificationObserver load_observer( |
| 152 NOTIFICATION_LOAD_STOP, |
| 153 Source<NavigationController>( |
| 154 &shell()->web_contents()->GetController())); |
| 155 bool result = content::ExecuteJavaScript( |
| 156 window->web_contents()->GetRenderViewHost(), |
| 157 L"", ASCIIToWide(script)); |
| 158 load_observer.Wait(); |
| 159 return result; |
| 160 } |
| 161 |
| 162 void SetUpCommandLine(CommandLine* command_line) { |
| 163 command_line->AppendSwitch(switches::kSitePerProcess); |
| 164 } |
| 165 }; |
| 166 |
| 167 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { |
| 168 ASSERT_TRUE(test_server()->Start()); |
| 169 net::TestServer https_server( |
| 170 net::TestServer::TYPE_HTTPS, |
| 171 net::TestServer::kLocalhost, |
| 172 FilePath(FILE_PATH_LITERAL("content/test/data"))); |
| 173 ASSERT_TRUE(https_server.Start()); |
| 174 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); |
| 175 |
| 176 NavigateToURL(shell(), main_url); |
| 177 |
| 178 SitePerProcessWebContentsObserver observer(shell()->web_contents()); |
| 179 { |
| 180 // Load same-site page into Iframe. |
| 181 GURL http_url(test_server()->GetURL("files/title1.html")); |
| 182 EXPECT_TRUE(NavigateIframeToURL(shell(), http_url, "test")); |
| 183 EXPECT_EQ(observer.navigation_url(), http_url); |
| 184 EXPECT_TRUE(observer.navigation_succeeded()); |
| 185 } |
| 186 |
| 187 { |
| 188 // Load cross-site page into Iframe. |
| 189 GURL https_url(https_server.GetURL("files/title1.html")); |
| 190 EXPECT_TRUE(NavigateIframeToURL(shell(), https_url, "test")); |
| 191 EXPECT_EQ(observer.navigation_url(), https_url); |
| 192 EXPECT_FALSE(observer.navigation_succeeded()); |
| 193 } |
| 194 } |
| 195 |
| 196 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframeRedirectOnce) { |
| 197 ASSERT_TRUE(test_server()->Start()); |
| 198 net::TestServer https_server( |
| 199 net::TestServer::TYPE_HTTPS, |
| 200 net::TestServer::kLocalhost, |
| 201 FilePath(FILE_PATH_LITERAL("content/test/data"))); |
| 202 ASSERT_TRUE(https_server.Start()); |
| 203 |
| 204 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); |
| 205 GURL http_url(test_server()->GetURL("files/title1.html")); |
| 206 GURL https_url(https_server.GetURL("files/title1.html")); |
| 207 |
| 208 NavigateToURL(shell(), main_url); |
| 209 |
| 210 SitePerProcessWebContentsObserver observer(shell()->web_contents()); |
| 211 { |
| 212 // Load cross-site client-redirect page into Iframe. |
| 213 // Should be blocked. |
| 214 GURL client_redirect_https_url(https_server.GetURL( |
| 215 "client-redirect?files/title1.html")); |
| 216 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 217 client_redirect_https_url, "test")); |
| 218 // DidFailProvisionalLoad when navigating to client_redirect_https_url. |
| 219 EXPECT_EQ(observer.navigation_url(), client_redirect_https_url); |
| 220 EXPECT_FALSE(observer.navigation_succeeded()); |
| 221 } |
| 222 |
| 223 { |
| 224 // Load cross-site server-redirect page into Iframe, |
| 225 // which redirects to same-site page. |
| 226 GURL server_redirect_http_url(https_server.GetURL( |
| 227 "server-redirect?" + http_url.spec())); |
| 228 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 229 server_redirect_http_url, "test")); |
| 230 EXPECT_EQ(observer.navigation_url(), http_url); |
| 231 EXPECT_TRUE(observer.navigation_succeeded()); |
| 232 } |
| 233 |
| 234 { |
| 235 // Load cross-site server-redirect page into Iframe, |
| 236 // which redirects to cross-site page. |
| 237 GURL server_redirect_http_url(https_server.GetURL( |
| 238 "server-redirect?files/title1.html")); |
| 239 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 240 server_redirect_http_url, "test")); |
| 241 // DidFailProvisionalLoad when navigating to https_url. |
| 242 EXPECT_EQ(observer.navigation_url(), https_url); |
| 243 EXPECT_FALSE(observer.navigation_succeeded()); |
| 244 } |
| 245 |
| 246 { |
| 247 // Load same-site server-redirect page into Iframe, |
| 248 // which redirects to cross-site page. |
| 249 GURL server_redirect_http_url(test_server()->GetURL( |
| 250 "server-redirect?" + https_url.spec())); |
| 251 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 252 server_redirect_http_url, "test")); |
| 253 |
| 254 EXPECT_EQ(observer.navigation_url(), https_url); |
| 255 EXPECT_FALSE(observer.navigation_succeeded()); |
| 256 } |
| 257 |
| 258 { |
| 259 // Load same-site client-redirect page into Iframe, |
| 260 // which redirects to cross-site page. |
| 261 GURL client_redirect_http_url(test_server()->GetURL( |
| 262 "client-redirect?" + https_url.spec())); |
| 263 |
| 264 RedirectNotificationObserver load_observer2( |
| 265 NOTIFICATION_LOAD_STOP, |
| 266 Source<NavigationController>( |
| 267 &shell()->web_contents()->GetController())); |
| 268 |
| 269 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 270 client_redirect_http_url, "test")); |
| 271 |
| 272 // Same-site Client-Redirect Page should be loaded successfully. |
| 273 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); |
| 274 EXPECT_TRUE(observer.navigation_succeeded()); |
| 275 |
| 276 // Redirecting to Cross-site Page should be blocked. |
| 277 load_observer2.Wait(); |
| 278 EXPECT_EQ(observer.navigation_url(), https_url); |
| 279 EXPECT_FALSE(observer.navigation_succeeded()); |
| 280 } |
| 281 |
| 282 { |
| 283 // Load same-site server-redirect page into Iframe, |
| 284 // which redirects to same-site page. |
| 285 GURL server_redirect_http_url(test_server()->GetURL( |
| 286 "server-redirect?files/title1.html")); |
| 287 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 288 server_redirect_http_url, "test")); |
| 289 EXPECT_EQ(observer.navigation_url(), http_url); |
| 290 EXPECT_TRUE(observer.navigation_succeeded()); |
| 291 } |
| 292 |
| 293 { |
| 294 // Load same-site client-redirect page into Iframe, |
| 295 // which redirects to same-site page. |
| 296 GURL client_redirect_http_url(test_server()->GetURL( |
| 297 "client-redirect?" + http_url.spec())); |
| 298 RedirectNotificationObserver load_observer2( |
| 299 NOTIFICATION_LOAD_STOP, |
| 300 Source<NavigationController>( |
| 301 &shell()->web_contents()->GetController())); |
| 302 |
| 303 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 304 client_redirect_http_url, "test")); |
| 305 |
| 306 // Same-site Client-Redirect Page should be loaded successfully. |
| 307 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); |
| 308 EXPECT_TRUE(observer.navigation_succeeded()); |
| 309 |
| 310 // Redirecting to Same-site Page should be loaded successfully. |
| 311 load_observer2.Wait(); |
| 312 EXPECT_EQ(observer.navigation_url(), http_url); |
| 313 EXPECT_TRUE(observer.navigation_succeeded()); |
| 314 } |
| 315 } |
| 316 |
| 317 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 318 CrossSiteIframeRedirectTwice) { |
| 319 ASSERT_TRUE(test_server()->Start()); |
| 320 net::TestServer https_server( |
| 321 net::TestServer::TYPE_HTTPS, |
| 322 net::TestServer::kLocalhost, |
| 323 FilePath(FILE_PATH_LITERAL("content/test/data"))); |
| 324 ASSERT_TRUE(https_server.Start()); |
| 325 |
| 326 GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); |
| 327 GURL http_url(test_server()->GetURL("files/title1.html")); |
| 328 GURL https_url(https_server.GetURL("files/title1.html")); |
| 329 |
| 330 NavigateToURL(shell(), main_url); |
| 331 |
| 332 SitePerProcessWebContentsObserver observer(shell()->web_contents()); |
| 333 { |
| 334 // Load client-redirect page pointing to a cross-site client-redirect page, |
| 335 // which eventually redirects back to same-site page. |
| 336 GURL client_redirect_https_url(https_server.GetURL( |
| 337 "client-redirect?" + http_url.spec())); |
| 338 GURL client_redirect_http_url(test_server()->GetURL( |
| 339 "client-redirect?" + client_redirect_https_url.spec())); |
| 340 |
| 341 // We should wait until second client redirect get cancelled. |
| 342 RedirectNotificationObserver load_observer2( |
| 343 NOTIFICATION_LOAD_STOP, |
| 344 Source<NavigationController>( |
| 345 &shell()->web_contents()->GetController())); |
| 346 |
| 347 EXPECT_TRUE(NavigateIframeToURL(shell(), client_redirect_http_url, "test")); |
| 348 |
| 349 // DidFailProvisionalLoad when navigating to client_redirect_https_url. |
| 350 load_observer2.Wait(); |
| 351 EXPECT_EQ(observer.navigation_url(), client_redirect_https_url); |
| 352 EXPECT_FALSE(observer.navigation_succeeded()); |
| 353 } |
| 354 |
| 355 { |
| 356 // Load server-redirect page pointing to a cross-site server-redirect page, |
| 357 // which eventually redirect back to same-site page. |
| 358 GURL server_redirect_https_url(https_server.GetURL( |
| 359 "server-redirect?" + http_url.spec())); |
| 360 GURL server_redirect_http_url(test_server()->GetURL( |
| 361 "server-redirect?" + server_redirect_https_url.spec())); |
| 362 EXPECT_TRUE(NavigateIframeToURL(shell(), |
| 363 server_redirect_http_url, "test")); |
| 364 EXPECT_EQ(observer.navigation_url(), http_url); |
| 365 EXPECT_TRUE(observer.navigation_succeeded()); |
| 366 } |
| 367 |
| 368 { |
| 369 // Load server-redirect page pointing to a cross-site server-redirect page, |
| 370 // which eventually redirects back to cross-site page. |
| 371 GURL server_redirect_https_url(https_server.GetURL( |
| 372 "server-redirect?" + https_url.spec())); |
| 373 GURL server_redirect_http_url(test_server()->GetURL( |
| 374 "server-redirect?" + server_redirect_https_url.spec())); |
| 375 EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test")); |
| 376 |
| 377 // DidFailProvisionalLoad when navigating to https_url. |
| 378 EXPECT_EQ(observer.navigation_url(), https_url); |
| 379 EXPECT_FALSE(observer.navigation_succeeded()); |
| 380 } |
| 381 |
| 382 { |
| 383 // Load server-redirect page pointing to a cross-site client-redirect page, |
| 384 // which eventually redirects back to same-site page. |
| 385 GURL client_redirect_http_url(https_server.GetURL( |
| 386 "client-redirect?" + http_url.spec())); |
| 387 GURL server_redirect_http_url(test_server()->GetURL( |
| 388 "server-redirect?" + client_redirect_http_url.spec())); |
| 389 EXPECT_TRUE(NavigateIframeToURL(shell(), server_redirect_http_url, "test")); |
| 390 |
| 391 // DidFailProvisionalLoad when navigating to client_redirect_http_url. |
| 392 EXPECT_EQ(observer.navigation_url(), client_redirect_http_url); |
| 393 EXPECT_FALSE(observer.navigation_succeeded()); |
| 394 } |
| 395 } |
| 396 |
| 397 } |
OLD | NEW |