Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / loader / resource_dispatcher_host_browsertest.cc
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/memory/ref_counted.h"
6 #include "base/strings/string_util.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "content/browser/download/download_manager_impl.h"
10 #include "content/browser/web_contents/web_contents_impl.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/common/url_constants.h"
15 #include "content/public/test/browser_test_utils.h"
16 #include "content/public/test/content_browser_test.h"
17 #include "content/public/test/content_browser_test_utils.h"
18 #include "content/public/test/test_utils.h"
19 #include "content/shell/browser/shell.h"
20 #include "content/shell/browser/shell_content_browser_client.h"
21 #include "content/shell/browser/shell_network_delegate.h"
22 #include "net/base/net_errors.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "net/test/embedded_test_server/http_request.h"
25 #include "net/test/embedded_test_server/http_response.h"
26 #include "net/test/url_request/url_request_failed_job.h"
27 #include "net/test/url_request/url_request_mock_http_job.h"
28
29 using base::ASCIIToUTF16;
30
31 namespace content {
32
33 class ResourceDispatcherHostBrowserTest : public ContentBrowserTest,
34                                           public DownloadManager::Observer {
35  public:
36   ResourceDispatcherHostBrowserTest() : got_downloads_(false) {}
37
38  protected:
39   void SetUpOnMainThread() override {
40     base::FilePath path = GetTestFilePath("", "");
41     BrowserThread::PostTask(
42         BrowserThread::IO,
43         FROM_HERE,
44         base::Bind(
45             &net::URLRequestMockHTTPJob::AddUrlHandler,
46             path,
47             make_scoped_refptr(content::BrowserThread::GetBlockingPool())));
48     BrowserThread::PostTask(
49         BrowserThread::IO, FROM_HERE,
50         base::Bind(&net::URLRequestFailedJob::AddUrlHandler));
51   }
52
53   void OnDownloadCreated(DownloadManager* manager,
54                          DownloadItem* item) override {
55     if (!got_downloads_)
56       got_downloads_ = !!manager->InProgressCount();
57   }
58
59   GURL GetMockURL(const std::string& file) {
60     return net::URLRequestMockHTTPJob::GetMockUrl(
61         base::FilePath().AppendASCII(file));
62   }
63
64   void CheckTitleTest(const GURL& url,
65                       const std::string& expected_title) {
66     base::string16 expected_title16(ASCIIToUTF16(expected_title));
67     TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
68     NavigateToURL(shell(), url);
69     EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
70   }
71
72   bool GetPopupTitle(const GURL& url, base::string16* title) {
73     NavigateToURL(shell(), url);
74
75     ShellAddedObserver new_shell_observer;
76
77     // Create dynamic popup.
78     if (!ExecuteScript(shell()->web_contents(), "OpenPopup();"))
79       return false;
80
81     Shell* new_shell = new_shell_observer.GetShell();
82     *title = new_shell->web_contents()->GetTitle();
83     return true;
84   }
85
86   std::string GetCookies(const GURL& url) {
87     return content::GetCookies(
88         shell()->web_contents()->GetBrowserContext(), url);
89   }
90
91   bool got_downloads() const { return got_downloads_; }
92
93  private:
94   bool got_downloads_;
95 };
96
97 // Test title for content created by javascript window.open().
98 // See http://crbug.com/5988
99 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle1) {
100   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
101
102   GURL url(embedded_test_server()->GetURL("/dynamic1.html"));
103   base::string16 title;
104   ASSERT_TRUE(GetPopupTitle(url, &title));
105   EXPECT_TRUE(StartsWith(title, ASCIIToUTF16("My Popup Title"), true))
106       << "Actual title: " << title;
107 }
108
109 // Test title for content created by javascript window.open().
110 // See http://crbug.com/5988
111 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, DynamicTitle2) {
112   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
113
114   GURL url(embedded_test_server()->GetURL("/dynamic2.html"));
115   base::string16 title;
116   ASSERT_TRUE(GetPopupTitle(url, &title));
117   EXPECT_TRUE(StartsWith(title, ASCIIToUTF16("My Dynamic Title"), true))
118       << "Actual title: " << title;
119 }
120
121 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
122                        SniffHTMLWithNoContentType) {
123   CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
124                  "Content Sniffer Test 0");
125 }
126
127 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
128                        RespectNoSniffDirective) {
129   CheckTitleTest(GetMockURL("nosniff-test.html"),
130                  "mock.http/nosniff-test.html");
131 }
132
133 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
134                        DoNotSniffHTMLFromTextPlain) {
135   CheckTitleTest(GetMockURL("content-sniffer-test1.html"),
136                  "mock.http/content-sniffer-test1.html");
137 }
138
139 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
140                        DoNotSniffHTMLFromImageGIF) {
141   CheckTitleTest(GetMockURL("content-sniffer-test2.html"),
142                  "mock.http/content-sniffer-test2.html");
143 }
144
145 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
146                        SniffNoContentTypeNoData) {
147   // Make sure no downloads start.
148   BrowserContext::GetDownloadManager(
149       shell()->web_contents()->GetBrowserContext())->AddObserver(this);
150   CheckTitleTest(GetMockURL("content-sniffer-test3.html"),
151                  "Content Sniffer Test 3");
152   EXPECT_EQ(1u, Shell::windows().size());
153   ASSERT_FALSE(got_downloads());
154 }
155
156 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
157                        ContentDispositionEmpty) {
158   CheckTitleTest(GetMockURL("content-disposition-empty.html"), "success");
159 }
160
161 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
162                        ContentDispositionInline) {
163   CheckTitleTest(GetMockURL("content-disposition-inline.html"), "success");
164 }
165
166 // Test for bug #1091358.
167 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, SyncXMLHttpRequest) {
168   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
169   NavigateToURL(
170       shell(), embedded_test_server()->GetURL("/sync_xmlhttprequest.html"));
171
172   // Let's check the XMLHttpRequest ran successfully.
173   bool success = false;
174   EXPECT_TRUE(ExecuteScriptAndExtractBool(
175       shell()->web_contents(),
176       "window.domAutomationController.send(DidSyncRequestSucceed());",
177       &success));
178   EXPECT_TRUE(success);
179 }
180
181 // If this flakes, use http://crbug.com/62776.
182 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
183                        SyncXMLHttpRequest_Disallowed) {
184   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
185   NavigateToURL(
186       shell(),
187       embedded_test_server()->GetURL("/sync_xmlhttprequest_disallowed.html"));
188
189   // Let's check the XMLHttpRequest ran successfully.
190   bool success = false;
191   EXPECT_TRUE(ExecuteScriptAndExtractBool(
192       shell()->web_contents(),
193       "window.domAutomationController.send(DidSucceed());",
194       &success));
195   EXPECT_TRUE(success);
196 }
197
198 // Test for bug #1159553 -- A synchronous xhr (whose content-type is
199 // downloadable) would trigger download and hang the renderer process,
200 // if executed while navigating to a new page.
201 // Disabled on Mac: see http://crbug.com/56264
202 #if defined(OS_MACOSX)
203 #define MAYBE_SyncXMLHttpRequest_DuringUnload \
204   DISABLED_SyncXMLHttpRequest_DuringUnload
205 #else
206 #define MAYBE_SyncXMLHttpRequest_DuringUnload SyncXMLHttpRequest_DuringUnload
207 #endif
208 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
209                        MAYBE_SyncXMLHttpRequest_DuringUnload) {
210   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
211   BrowserContext::GetDownloadManager(
212       shell()->web_contents()->GetBrowserContext())->AddObserver(this);
213
214   CheckTitleTest(
215       embedded_test_server()->GetURL("/sync_xmlhttprequest_during_unload.html"),
216       "sync xhr on unload");
217
218   // Navigate to a new page, to dispatch unload event and trigger xhr.
219   // (the bug would make this step hang the renderer).
220   CheckTitleTest(
221       embedded_test_server()->GetURL("/title2.html"), "Title Of Awesomeness");
222
223   ASSERT_FALSE(got_downloads());
224 }
225
226 // Flaky everywhere. http://crbug.com/130404
227 // Tests that onunload is run for cross-site requests.  (Bug 1114994)
228 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
229                        DISABLED_CrossSiteOnunloadCookie) {
230   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
231
232   GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
233   CheckTitleTest(url, "set cookie on unload");
234
235   // Navigate to a new cross-site page, to dispatch unload event and set the
236   // cookie.
237   CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
238                  "Content Sniffer Test 0");
239
240   // Check that the cookie was set.
241   EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
242 }
243
244 // If this flakes, use http://crbug.com/130404
245 // Tests that onunload is run for cross-site requests to URLs that complete
246 // without network loads (e.g., about:blank, data URLs).
247 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
248                        DISABLED_CrossSiteImmediateLoadOnunloadCookie) {
249   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
250
251   GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
252   CheckTitleTest(url, "set cookie on unload");
253
254   // Navigate to a cross-site page that loads immediately without making a
255   // network request.  The unload event should still be run.
256   NavigateToURL(shell(), GURL(url::kAboutBlankURL));
257
258   // Check that the cookie was set.
259   EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
260 }
261
262 namespace {
263
264 // Handles |request| by serving a redirect response.
265 scoped_ptr<net::test_server::HttpResponse> NoContentResponseHandler(
266     const std::string& path,
267     const net::test_server::HttpRequest& request) {
268   if (!StartsWithASCII(path, request.relative_url, true))
269     return scoped_ptr<net::test_server::HttpResponse>();
270
271   scoped_ptr<net::test_server::BasicHttpResponse> http_response(
272       new net::test_server::BasicHttpResponse);
273   http_response->set_code(net::HTTP_NO_CONTENT);
274   return http_response.Pass();
275 }
276
277 }  // namespace
278
279 // Tests that the unload handler is not run for 204 responses.
280 // If this flakes use http://crbug.com/80596.
281 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
282                        CrossSiteNoUnloadOn204) {
283   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
284
285   // Start with a URL that sets a cookie in its unload handler.
286   GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
287   CheckTitleTest(url, "set cookie on unload");
288
289   // Navigate to a cross-site URL that returns a 204 No Content response.
290   const char kNoContentPath[] = "/nocontent";
291   embedded_test_server()->RegisterRequestHandler(
292       base::Bind(&NoContentResponseHandler, kNoContentPath));
293   NavigateToURL(shell(), embedded_test_server()->GetURL(kNoContentPath));
294
295   // Check that the unload cookie was not set.
296   EXPECT_EQ("", GetCookies(url));
297 }
298
299 #if !defined(OS_MACOSX)
300 // Tests that the onbeforeunload and onunload logic is short-circuited if the
301 // old renderer is gone.  In that case, we don't want to wait for the old
302 // renderer to run the handlers.
303 // We need to disable this on Mac because the crash causes the OS CrashReporter
304 // process to kick in to analyze the poor dead renderer.  Unfortunately, if the
305 // app isn't stripped of debug symbols, this takes about five minutes to
306 // complete and isn't conducive to quick turnarounds. As we don't currently
307 // strip the app on the build bots, this is bad times.
308 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CrossSiteAfterCrash) {
309   // Make sure we have a live process before trying to kill it.
310   NavigateToURL(shell(), GURL("about:blank"));
311
312   // Cause the renderer to crash.
313   RenderProcessHostWatcher crash_observer(
314       shell()->web_contents(),
315       RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
316   NavigateToURL(shell(), GURL(kChromeUICrashURL));
317   // Wait for browser to notice the renderer crash.
318   crash_observer.Wait();
319
320   // Navigate to a new cross-site page.  The browser should not wait around for
321   // the old renderer's on{before}unload handlers to run.
322   CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
323                  "Content Sniffer Test 0");
324 }
325 #endif  // !defined(OS_MACOSX)
326
327 // Tests that cross-site navigations work when the new page does not go through
328 // the BufferedEventHandler (e.g., non-http{s} URLs).  (Bug 1225872)
329 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
330                        CrossSiteNavigationNonBuffered) {
331   // Start with an HTTP page.
332   CheckTitleTest(GetMockURL("content-sniffer-test0.html"),
333                  "Content Sniffer Test 0");
334
335   // Now load a file:// page, which does not use the BufferedEventHandler.
336   // Make sure that the page loads and displays a title, and doesn't get stuck.
337   GURL url = GetTestUrl("", "title2.html");
338   CheckTitleTest(url, "Title Of Awesomeness");
339 }
340
341 // Flaky everywhere. http://crbug.com/130404
342 // Tests that a cross-site navigation to an error page (resulting in the link
343 // doctor page) still runs the onunload handler and can support navigations
344 // away from the link doctor page.  (Bug 1235537)
345 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
346                        DISABLED_CrossSiteNavigationErrorPage) {
347   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
348
349   GURL url(embedded_test_server()->GetURL("/onunload_cookie.html"));
350   CheckTitleTest(url, "set cookie on unload");
351
352   // Navigate to a new cross-site URL that results in an error.
353   // TODO(creis): If this causes crashes or hangs, it might be for the same
354   // reason as ErrorPageTest::DNSError.  See bug 1199491 and
355   // http://crbug.com/22877.
356   GURL failed_url = net::URLRequestFailedJob::GetMockHttpUrl(
357       net::ERR_NAME_NOT_RESOLVED);
358   NavigateToURL(shell(), failed_url);
359
360   EXPECT_NE(ASCIIToUTF16("set cookie on unload"),
361             shell()->web_contents()->GetTitle());
362
363   // Check that the cookie was set, meaning that the onunload handler ran.
364   EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
365
366   // Check that renderer-initiated navigations still work.  In a previous bug,
367   // the ResourceDispatcherHost would think that such navigations were
368   // cross-site, because we didn't clean up from the previous request.  Since
369   // WebContentsImpl was in the NORMAL state, it would ignore the attempt to run
370   // the onunload handler, and the navigation would fail. We can't test by
371   // redirecting to javascript:window.location='someURL', since javascript:
372   // URLs are prohibited by policy from interacting with sensitive chrome
373   // pages of which the error page is one.  Instead, use automation to kick
374   // off the navigation, and wait to see that the tab loads.
375   base::string16 expected_title16(ASCIIToUTF16("Title Of Awesomeness"));
376   TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
377
378   bool success;
379   GURL test_url(embedded_test_server()->GetURL("/title2.html"));
380   std::string redirect_script = "window.location='" +
381       test_url.possibly_invalid_spec() + "';" +
382       "window.domAutomationController.send(true);";
383   EXPECT_TRUE(ExecuteScriptAndExtractBool(
384       shell()->web_contents(),
385       redirect_script,
386       &success));
387   EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
388 }
389
390 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
391                        CrossSiteNavigationErrorPage2) {
392   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
393
394   GURL url(embedded_test_server()->GetURL("/title2.html"));
395   CheckTitleTest(url, "Title Of Awesomeness");
396
397   // Navigate to a new cross-site URL that results in an error.
398   // TODO(creis): If this causes crashes or hangs, it might be for the same
399   // reason as ErrorPageTest::DNSError.  See bug 1199491 and
400   // http://crbug.com/22877.
401   GURL failed_url = net::URLRequestFailedJob::GetMockHttpUrl(
402       net::ERR_NAME_NOT_RESOLVED);
403
404   NavigateToURL(shell(), failed_url);
405   EXPECT_NE(ASCIIToUTF16("Title Of Awesomeness"),
406             shell()->web_contents()->GetTitle());
407
408   // Repeat navigation.  We are testing that this completes.
409   NavigateToURL(shell(), failed_url);
410   EXPECT_NE(ASCIIToUTF16("Title Of Awesomeness"),
411             shell()->web_contents()->GetTitle());
412 }
413
414 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
415                        CrossOriginRedirectBlocked) {
416   // We expect the following URL requests from this test:
417   // 1-  http://mock.http/cross-origin-redirect-blocked.html
418   // 2-  http://mock.http/redirect-to-title2.html
419   // 3-  http://mock.http/title2.html
420   //
421   // If the redirect in #2 were not blocked, we'd also see a request
422   // for http://mock.http:4000/title2.html, and the title would be different.
423   CheckTitleTest(GetMockURL("cross-origin-redirect-blocked.html"),
424                  "Title Of More Awesomeness");
425 }
426
427 // Tests that ResourceRequestInfoImpl is updated correctly on failed
428 // requests, to prevent calling Read on a request that has already failed.
429 // See bug 40250.
430 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest,
431                        CrossSiteFailedRequest) {
432   // Visit another URL first to trigger a cross-site navigation.
433   NavigateToURL(shell(), GetTestUrl("", "simple_page.html"));
434
435   // Visit a URL that fails without calling ResourceDispatcherHost::Read.
436   GURL broken_url("chrome://theme");
437   NavigateToURL(shell(), broken_url);
438 }
439
440 namespace {
441
442 scoped_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
443     const std::string& request_path,
444     const net::test_server::HttpRequest& request) {
445   if (!StartsWithASCII(request.relative_url, request_path, true))
446     return scoped_ptr<net::test_server::HttpResponse>();
447
448   scoped_ptr<net::test_server::BasicHttpResponse> http_response(
449       new net::test_server::BasicHttpResponse);
450   http_response->set_code(net::HTTP_FOUND);
451   http_response->AddCustomHeader(
452       "Location", request.relative_url.substr(request_path.length()));
453   return http_response.Pass();
454 }
455
456 }  // namespace
457
458 // Test that we update the cookie policy URLs correctly when transferring
459 // navigations.
460 IN_PROC_BROWSER_TEST_F(ResourceDispatcherHostBrowserTest, CookiePolicy) {
461   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
462   embedded_test_server()->RegisterRequestHandler(
463       base::Bind(&HandleRedirectRequest, "/redirect?"));
464
465   std::string set_cookie_url(base::StringPrintf(
466       "http://localhost:%d/set_cookie.html", embedded_test_server()->port()));
467   GURL url(embedded_test_server()->GetURL("/redirect?" + set_cookie_url));
468
469   ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
470   ShellNetworkDelegate::SetAcceptAllCookies(false);
471
472   CheckTitleTest(url, "cookie set");
473 }
474
475 }  // namespace content