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 |