Chromium Code Reviews| 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 { | |
|
nasko
2012/12/06 23:37:47
This doesn't look much different than other observ
| |
| 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 |