blob: d89b874cccea7b0627e825c4f477fac2f86f9ef9 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]fac06f332011-06-14 05:30:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avi933295f52017-01-03 19:50:275#include <memory>
dcheng36b6aec92015-12-26 06:16:366#include <utility>
avi933295f52017-01-03 19:50:277#include <vector>
dcheng36b6aec92015-12-26 06:16:368
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:589#include "base/command_line.h"
Avi Drissmanadac21992023-01-11 23:46:3910#include "base/functional/bind.h"
11#include "base/functional/callback_helpers.h"
xunjieli0332c192014-09-10 23:23:3112#include "base/memory/ref_counted.h"
megjablond5ac7d52015-10-22 23:56:1213#include "base/run_loop.h"
Tsuyoshi Horoffd487362024-08-29 21:11:1714#include "base/strings/string_number_conversions.h"
[email protected]348fbaac2013-06-11 06:31:5115#include "base/strings/string_util.h"
[email protected]fbaccee2013-08-12 23:24:0216#include "base/strings/stringprintf.h"
[email protected]74ebfb12013-06-07 20:48:0017#include "base/strings/utf_string_conversions.h"
Guido Urdanetaef4e91942020-11-09 15:06:2418#include "base/test/bind.h"
avib7348942015-12-25 20:57:1019#include "build/build_config.h"
[email protected]b83fbfe82012-04-21 00:05:0720#include "content/browser/download/download_manager_impl.h"
[email protected]93ddb3c2012-04-11 21:44:2921#include "content/browser/web_contents/web_contents_impl.h"
[email protected]b83fbfe82012-04-21 00:05:0722#include "content/public/browser/browser_context.h"
Eric Seckler8652dcd52018-09-20 10:42:2823#include "content/public/browser/browser_task_traits.h"
[email protected]b83fbfe82012-04-21 00:05:0724#include "content/public/browser/browser_thread.h"
Yoichi Osatoe0400142023-05-30 19:35:4025#include "content/public/browser/network_service_util.h"
Lukasz Anforowicz5440a8e2017-09-28 16:52:1026#include "content/public/browser/render_frame_host.h"
Lukasz Anforowicz7d7da7f2018-07-31 00:21:5927#include "content/public/browser/site_isolation_policy.h"
[email protected]b83fbfe82012-04-21 00:05:0728#include "content/public/browser/web_contents.h"
Hans Wennborg5ffd1392019-10-16 11:00:0229#include "content/public/common/content_client.h"
[email protected]b83fbfe82012-04-21 00:05:0730#include "content/public/common/url_constants.h"
Peter Kasting919ce652020-05-07 10:22:3631#include "content/public/test/browser_test.h"
[email protected]35daebe02012-07-20 05:40:5932#include "content/public/test/browser_test_utils.h"
[email protected]6e9def12014-03-27 20:23:2833#include "content/public/test/content_browser_test.h"
Scott Violet99861992023-02-08 01:20:1234#include "content/public/test/content_browser_test_content_browser_client.h"
[email protected]6e9def12014-03-27 20:23:2835#include "content/public/test/content_browser_test_utils.h"
megjablond5ac7d52015-10-22 23:56:1236#include "content/public/test/test_navigation_observer.h"
[email protected]854e1312012-07-30 17:26:3037#include "content/public/test/test_utils.h"
John Abd-El-Malek2d2173732018-04-25 13:40:5138#include "content/public/test/url_loader_interceptor.h"
[email protected]de7d61ff2013-08-20 11:30:4139#include "content/shell/browser/shell.h"
Matt Menkefcbb1bd72018-01-31 21:53:1240#include "net/base/filename_util.h"
Benoit Lize0a370db72017-08-28 17:01:2941#include "net/base/load_flags.h"
[email protected]b83fbfe82012-04-21 00:05:0742#include "net/base/net_errors.h"
mkwstb1d1a952016-06-22 14:58:0543#include "net/dns/mock_host_resolver.h"
Tsuyoshi Horoffd487362024-08-29 21:11:1744#include "net/http/http_status_code.h"
[email protected]0d31fbc2013-05-28 17:00:3745#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]0d31fbc2013-05-28 17:00:3746#include "net/test/embedded_test_server/http_request.h"
[email protected]74ebfb12013-06-07 20:48:0047#include "net/test/embedded_test_server/http_response.h"
xunjieli2906f152014-09-12 00:08:2348#include "net/test/url_request/url_request_failed_job.h"
xunjieli0332c192014-09-10 23:23:3149#include "net/test/url_request/url_request_mock_http_job.h"
John Abd-El-Malek21f3ea12018-03-03 00:53:1250#include "services/network/public/cpp/features.h"
arthursonzogni224aa612017-12-07 15:31:5151#include "testing/gmock/include/gmock/gmock.h"
Gyuyoung Kim107c2a02021-04-13 01:49:3052#include "third_party/blink/public/common/chrome_debug_urls.h"
Minggang Wangf6840ecf2019-07-29 05:15:0253#include "third_party/blink/public/common/loader/url_loader_throttle.h"
megjablond5ac7d52015-10-22 23:56:1254#include "url/gurl.h"
[email protected]fac06f332011-06-14 05:30:4455
[email protected]32956122013-12-25 07:29:2456using base::ASCIIToUTF16;
arthursonzogni224aa612017-12-07 15:31:5157using testing::HasSubstr;
58using testing::Not;
[email protected]32956122013-12-25 07:29:2459
[email protected]854e1312012-07-30 17:26:3060namespace content {
[email protected]b83fbfe82012-04-21 00:05:0761
John Abd-El-Malek6883212992018-04-25 22:32:2262class LoaderBrowserTest : public ContentBrowserTest,
63 public DownloadManager::Observer {
[email protected]fac06f332011-06-14 05:30:4464 public:
John Abd-El-Malek6883212992018-04-25 22:32:2265 LoaderBrowserTest() : got_downloads_(false) {}
[email protected]fac06f332011-06-14 05:30:4466
67 protected:
dchengc2282aa2014-10-21 12:07:5868 void SetUpOnMainThread() override {
[email protected]2dec8ec2013-02-07 19:20:3469 base::FilePath path = GetTestFilePath("", "");
Gabriel Charettee7cdc5cd2020-05-27 23:35:0570 GetIOThreadTaskRunner({})->PostTask(
71 FROM_HERE,
tzik0f14f192017-08-15 02:43:3372 base::BindOnce(&net::URLRequestMockHTTPJob::AddUrlHandlers, path));
Gabriel Charettee7cdc5cd2020-05-27 23:35:0573 GetIOThreadTaskRunner({})->PostTask(
74 FROM_HERE, base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
arthursonzogni224aa612017-12-07 15:31:5175 host_resolver()->AddRule("*", "127.0.0.1");
[email protected]b83fbfe82012-04-21 00:05:0776 }
77
Thanh Le006f25322017-09-13 17:38:0478 void CheckTitleTest(const GURL& url, const std::string& expected_title) {
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:5879 std::u16string expected_title16(ASCIIToUTF16(expected_title));
[email protected]854e1312012-07-30 17:26:3080 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
Alex Moshchuk765684f52019-09-21 01:16:4181 EXPECT_TRUE(NavigateToURL(shell(), url));
[email protected]b83fbfe82012-04-21 00:05:0782 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
83 }
84
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:5885 bool GetPopupTitle(const GURL& url, std::u16string* title) {
Alex Moshchuk765684f52019-09-21 01:16:4186 EXPECT_TRUE(NavigateToURL(shell(), url));
[email protected]854e1312012-07-30 17:26:3087
88 ShellAddedObserver new_shell_observer;
89
90 // Create dynamic popup.
Solomon Kinardab293bae2024-09-19 17:13:5191 if (!ExecJs(shell(), "OpenPopup();")) {
[email protected]854e1312012-07-30 17:26:3092 return false;
Solomon Kinardab293bae2024-09-19 17:13:5193 }
[email protected]854e1312012-07-30 17:26:3094
95 Shell* new_shell = new_shell_observer.GetShell();
96 *title = new_shell->web_contents()->GetTitle();
97 return true;
98 }
[email protected]b83fbfe82012-04-21 00:05:0799
100 std::string GetCookies(const GURL& url) {
Thanh Le006f25322017-09-13 17:38:04101 return content::GetCookies(shell()->web_contents()->GetBrowserContext(),
102 url);
[email protected]b83fbfe82012-04-21 00:05:07103 }
104
105 bool got_downloads() const { return got_downloads_; }
106
107 private:
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:58108 void SetUp() override {
109 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
110 "cors_exempt_header_list", "ExemptFoo");
111 ContentBrowserTest::SetUp();
112 }
113
[email protected]b83fbfe82012-04-21 00:05:07114 bool got_downloads_;
[email protected]fac06f332011-06-14 05:30:44115};
116
[email protected]fac06f332011-06-14 05:30:44117// Test title for content created by javascript window.open().
118// See http://crbug.com/5988
John Abd-El-Malek6883212992018-04-25 22:32:22119IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DynamicTitle1) {
svaldezc3a9a172015-11-03 22:01:33120 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]fac06f332011-06-14 05:30:44121
[email protected]0d31fbc2013-05-28 17:00:37122 GURL url(embedded_test_server()->GetURL("/dynamic1.html"));
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58123 std::u16string title;
[email protected]fac06f332011-06-14 05:30:44124 ASSERT_TRUE(GetPopupTitle(url, &title));
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02125 EXPECT_TRUE(
126 base::StartsWith(title, u"My Popup Title", base::CompareCase::SENSITIVE))
[email protected]fac06f332011-06-14 05:30:44127 << "Actual title: " << title;
128}
129
130// Test title for content created by javascript window.open().
131// See http://crbug.com/5988
John Abd-El-Malek6883212992018-04-25 22:32:22132IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DynamicTitle2) {
svaldezc3a9a172015-11-03 22:01:33133 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]fac06f332011-06-14 05:30:44134
[email protected]0d31fbc2013-05-28 17:00:37135 GURL url(embedded_test_server()->GetURL("/dynamic2.html"));
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58136 std::u16string title;
[email protected]fac06f332011-06-14 05:30:44137 ASSERT_TRUE(GetPopupTitle(url, &title));
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02138 EXPECT_TRUE(base::StartsWith(title, u"My Dynamic Title",
brettw94a2cc22015-07-01 19:26:54139 base::CompareCase::SENSITIVE))
[email protected]fac06f332011-06-14 05:30:44140 << "Actual title: " << title;
141}
[email protected]b83fbfe82012-04-21 00:05:07142
Dominic Farolino9c277c52019-07-16 10:56:05143// Tests that the renderer does not crash when issuing a stale-revalidation
144// request when the enable_referrers renderer preference is `false`. See
145// https://crbug.com/966140.
146IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
147 DisableReferrersStaleWhileRevalidate) {
148 ASSERT_TRUE(embedded_test_server()->Start());
149 WebContentsImpl* web_contents =
150 static_cast<WebContentsImpl*>(shell()->web_contents());
151
152 // Navigate to the page that will eventually fetch a stale-revalidation
153 // request. Ensure that the renderer has not crashed.
154 ASSERT_TRUE(NavigateToURL(
155 shell(), embedded_test_server()->GetURL("/stale-while-revalidate.html")));
156
Bruce Long1e3e1f542019-10-16 17:56:28157 // Force-disable the |enable_referrers| preference.
158 web_contents->GetMutableRendererPrefs()->enable_referrers = false;
159 web_contents->SyncRendererPrefs();
Dominic Farolino9c277c52019-07-16 10:56:05160
161 // Wait for the stale-while-revalidate tests to pass by observing the page's
162 // title. If the renderer crashes, the test immediately fails.
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02163 std::u16string expected_title = u"Pass";
Dominic Farolino9c277c52019-07-16 10:56:05164 TitleWatcher title_watcher(web_contents, expected_title);
165
166 // The invocation of runTest() below starts a test written in JavaScript, that
167 // after some time, creates a stale-revalidation request. The above IPC
168 // message should be handled by the renderer (thus updating its preferences),
169 // before this stale-revalidation request is sent. Technically nothing
170 // guarantees this will happen, so it is theoretically possible the test is
171 // racy, however in practice the renderer will always handle the IPC message
172 // before the stale-revalidation request. This is because the renderer is
173 // never completely blocked from the time the test starts.
Avi Drissmanc91bd8e2021-04-19 23:58:44174 EXPECT_TRUE(ExecJs(shell(), "runTest()"));
Dominic Farolino9c277c52019-07-16 10:56:05175 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
176}
177
John Abd-El-Malek6883212992018-04-25 22:32:22178IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SniffNoContentTypeNoData) {
[email protected]b83fbfe82012-04-21 00:05:07179 // Make sure no downloads start.
Lukasz Anforowicz48d83452021-05-12 02:58:20180 shell()
181 ->web_contents()
182 ->GetBrowserContext()
183 ->GetDownloadManager()
Thanh Le006f25322017-09-13 17:38:04184 ->AddObserver(this);
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43185 ASSERT_TRUE(embedded_test_server()->Start());
186 GURL url(embedded_test_server()->GetURL("/content-sniffer-test3.html"));
187 CheckTitleTest(url, "Content Sniffer Test 3");
[email protected]854e1312012-07-30 17:26:30188 EXPECT_EQ(1u, Shell::windows().size());
[email protected]30b97df2012-04-21 02:15:28189 ASSERT_FALSE(got_downloads());
[email protected]b83fbfe82012-04-21 00:05:07190}
191
Matt Menkefcbb1bd72018-01-31 21:53:12192// Make sure file URLs are not sniffed as HTML when they don't end in HTML.
John Abd-El-Malek6883212992018-04-25 22:32:22193IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DoNotSniffHTMLFromFileUrl) {
Matt Menkefcbb1bd72018-01-31 21:53:12194 base::FilePath path =
195 GetTestFilePath(nullptr, "content-sniffer-test5.not-html");
196 GURL file_url = net::FilePathToFileURL(path);
197 // If the file isn't rendered as HTML, the title will match the name of the
198 // file, rather than the contents of the file's title tag.
199 CheckTitleTest(file_url, path.BaseName().MaybeAsASCII());
200}
201
John Abd-El-Malek6883212992018-04-25 22:32:22202IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, ContentDispositionEmpty) {
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43203 ASSERT_TRUE(embedded_test_server()->Start());
204 GURL url(embedded_test_server()->GetURL("/content-disposition-empty.html"));
205 CheckTitleTest(url, "success");
[email protected]b83fbfe82012-04-21 00:05:07206}
207
John Abd-El-Malek6883212992018-04-25 22:32:22208IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, ContentDispositionInline) {
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43209 ASSERT_TRUE(embedded_test_server()->Start());
210 GURL url(embedded_test_server()->GetURL("/content-disposition-inline.html"));
211 CheckTitleTest(url, "success");
[email protected]b83fbfe82012-04-21 00:05:07212}
213
214// Test for bug #1091358.
John Abd-El-Malek6883212992018-04-25 22:32:22215IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SyncXMLHttpRequest) {
svaldezc3a9a172015-11-03 22:01:33216 ASSERT_TRUE(embedded_test_server()->Start());
Alex Moshchuk765684f52019-09-21 01:16:41217 EXPECT_TRUE(NavigateToURL(
218 shell(), embedded_test_server()->GetURL("/sync_xmlhttprequest.html")));
[email protected]b83fbfe82012-04-21 00:05:07219
220 // Let's check the XMLHttpRequest ran successfully.
Avi Drissmanc91bd8e2021-04-19 23:58:44221 EXPECT_EQ(true, EvalJs(shell(), "DidSyncRequestSucceed();"));
[email protected]b83fbfe82012-04-21 00:05:07222}
223
224// If this flakes, use http://crbug.com/62776.
John Abd-El-Malek6883212992018-04-25 22:32:22225IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SyncXMLHttpRequest_Disallowed) {
svaldezc3a9a172015-11-03 22:01:33226 ASSERT_TRUE(embedded_test_server()->Start());
Alex Moshchuk765684f52019-09-21 01:16:41227 EXPECT_TRUE(NavigateToURL(
228 shell(),
229 embedded_test_server()->GetURL("/sync_xmlhttprequest_disallowed.html")));
[email protected]b83fbfe82012-04-21 00:05:07230
231 // Let's check the XMLHttpRequest ran successfully.
Avi Drissmanc91bd8e2021-04-19 23:58:44232 EXPECT_EQ(true, EvalJs(shell(), "DidSucceed();"));
[email protected]b83fbfe82012-04-21 00:05:07233}
234
235// Test for bug #1159553 -- A synchronous xhr (whose content-type is
236// downloadable) would trigger download and hang the renderer process,
237// if executed while navigating to a new page.
[email protected]ac5e5c02013-07-04 05:50:28238// Disabled on Mac: see http://crbug.com/56264
Xiaohan Wangbf7702b92022-01-15 14:34:20239#if BUILDFLAG(IS_MAC)
[email protected]ac5e5c02013-07-04 05:50:28240#define MAYBE_SyncXMLHttpRequest_DuringUnload \
241 DISABLED_SyncXMLHttpRequest_DuringUnload
242#else
243#define MAYBE_SyncXMLHttpRequest_DuringUnload SyncXMLHttpRequest_DuringUnload
244#endif
John Abd-El-Malek6883212992018-04-25 22:32:22245IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
[email protected]ac5e5c02013-07-04 05:50:28246 MAYBE_SyncXMLHttpRequest_DuringUnload) {
svaldezc3a9a172015-11-03 22:01:33247 ASSERT_TRUE(embedded_test_server()->Start());
Lukasz Anforowicz48d83452021-05-12 02:58:20248 shell()
249 ->web_contents()
250 ->GetBrowserContext()
251 ->GetDownloadManager()
Thanh Le006f25322017-09-13 17:38:04252 ->AddObserver(this);
[email protected]b83fbfe82012-04-21 00:05:07253
254 CheckTitleTest(
[email protected]0d31fbc2013-05-28 17:00:37255 embedded_test_server()->GetURL("/sync_xmlhttprequest_during_unload.html"),
[email protected]854e1312012-07-30 17:26:30256 "sync xhr on unload");
[email protected]b83fbfe82012-04-21 00:05:07257
258 // Navigate to a new page, to dispatch unload event and trigger xhr.
259 // (the bug would make this step hang the renderer).
Thanh Le006f25322017-09-13 17:38:04260 CheckTitleTest(embedded_test_server()->GetURL("/title2.html"),
261 "Title Of Awesomeness");
[email protected]b83fbfe82012-04-21 00:05:07262
[email protected]30b97df2012-04-21 02:15:28263 ASSERT_FALSE(got_downloads());
[email protected]b83fbfe82012-04-21 00:05:07264}
265
tzik31f1ac02016-11-16 08:48:36266namespace {
267
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43268// Responds with a HungResponse for the specified URL to hang on the request.
John Abd-El-Malekff2fb3d12019-07-29 06:32:12269// It crashes the process.
Matt Menke7c6443c7a2018-06-12 19:00:56270//
271// |crash_network_service_callback| crashes the network service when invoked,
272// and must be called on the UI thread.
tzik31f1ac02016-11-16 08:48:36273std::unique_ptr<net::test_server::HttpResponse> CancelOnRequest(
274 const std::string& relative_url,
275 int child_id,
Matt Menke7c6443c7a2018-06-12 19:00:56276 base::RepeatingClosure crash_network_service_callback,
tzik31f1ac02016-11-16 08:48:36277 const net::test_server::HttpRequest& request) {
Solomon Kinardab293bae2024-09-19 17:13:51278 if (request.relative_url != relative_url) {
tzik31f1ac02016-11-16 08:48:36279 return nullptr;
Solomon Kinardab293bae2024-09-19 17:13:51280 }
tzik31f1ac02016-11-16 08:48:36281
Hiroshige Hayashizakib5e8a122024-02-26 14:44:07282 GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
283 crash_network_service_callback);
tzik31f1ac02016-11-16 08:48:36284
Jeremy Roman04f27c372017-10-27 15:20:55285 return std::make_unique<net::test_server::HungResponse>();
tzik31f1ac02016-11-16 08:48:36286}
287
288} // namespace
289
290// Tests the case where the request is cancelled by a layer above the
291// URLRequest, which passes the error on ResourceLoader teardown, rather than in
292// response to call to AsyncResourceHandler::OnResponseComplete.
Xing Liu067ce602020-07-30 19:30:31293// Failed on Android M builder. See crbug/1111427.
Xiaohan Wangbf7702b92022-01-15 14:34:20294#if BUILDFLAG(IS_ANDROID)
Xing Liu067ce602020-07-30 19:30:31295#define MAYBE_SyncXMLHttpRequest_Cancelled DISABLED_SyncXMLHttpRequest_Cancelled
296#else
297#define MAYBE_SyncXMLHttpRequest_Cancelled SyncXMLHttpRequest_Cancelled
298#endif
299IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, MAYBE_SyncXMLHttpRequest_Cancelled) {
Clark DuVallc2227ae2018-11-28 22:26:36300 // If network service is running in-process, we can't simulate a crash.
Solomon Kinardab293bae2024-09-19 17:13:51301 if (IsInProcessNetworkService()) {
Clark DuVallc2227ae2018-11-28 22:26:36302 return;
Solomon Kinardab293bae2024-09-19 17:13:51303 }
Clark DuVallc2227ae2018-11-28 22:26:36304
Makoto Shimazu833e1c72019-10-09 21:14:50305 embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
Lukasz Anforowicz5440a8e2017-09-28 16:52:10306 &CancelOnRequest, "/hung",
Emily Andrewsd15fd762024-12-10 20:41:54307 shell()
308 ->web_contents()
309 ->GetPrimaryMainFrame()
310 ->GetProcess()
311 ->GetDeprecatedID(),
Matt Menke7c6443c7a2018-06-12 19:00:56312 base::BindRepeating(&BrowserTestBase::SimulateNetworkServiceCrash,
313 base::Unretained(this))));
martijnb3624552016-11-30 08:06:09314
315 ASSERT_TRUE(embedded_test_server()->Start());
François Dorayc1afdeb2021-04-27 15:56:25316 WaitForLoadStop(shell()->web_contents());
martijnb3624552016-11-30 08:06:09317
Alex Moshchuk765684f52019-09-21 01:16:41318 EXPECT_TRUE(NavigateToURL(
319 shell(),
320 embedded_test_server()->GetURL("/sync_xmlhttprequest_cancelled.html")));
tzik31f1ac02016-11-16 08:48:36321
tzik31f1ac02016-11-16 08:48:36322 // 19 is the value of NETWORK_ERROR on DOMException.
Avi Drissmanc91bd8e2021-04-19 23:58:44323 EXPECT_EQ(19, EvalJs(shell(), "getErrorCode();"));
tzik31f1ac02016-11-16 08:48:36324}
325
benwells13a1ded92014-11-04 03:41:29326// Flaky everywhere. http://crbug.com/130404
[email protected]b83fbfe82012-04-21 00:05:07327// Tests that onunload is run for cross-site requests. (Bug 1114994)
John Abd-El-Malek6883212992018-04-25 22:32:22328IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, DISABLED_CrossSiteOnunloadCookie) {
svaldezc3a9a172015-11-03 22:01:33329 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]b83fbfe82012-04-21 00:05:07330
[email protected]0d31fbc2013-05-28 17:00:37331 GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
[email protected]854e1312012-07-30 17:26:30332 CheckTitleTest(url, "set cookie on unload");
[email protected]b83fbfe82012-04-21 00:05:07333
334 // Navigate to a new cross-site page, to dispatch unload event and set the
335 // cookie.
tfarina5e7b57232015-10-17 23:37:40336 CheckTitleTest(
337 net::URLRequestMockHTTPJob::GetMockUrl("content-sniffer-test0.html"),
338 "Content Sniffer Test 0");
[email protected]b83fbfe82012-04-21 00:05:07339
340 // Check that the cookie was set.
341 EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
342}
343
[email protected]854e1312012-07-30 17:26:30344// If this flakes, use http://crbug.com/130404
[email protected]b83fbfe82012-04-21 00:05:07345// Tests that onunload is run for cross-site requests to URLs that complete
346// without network loads (e.g., about:blank, data URLs).
John Abd-El-Malek6883212992018-04-25 22:32:22347IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
[email protected]91f60e52012-10-24 21:46:26348 DISABLED_CrossSiteImmediateLoadOnunloadCookie) {
svaldezc3a9a172015-11-03 22:01:33349 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]b83fbfe82012-04-21 00:05:07350
[email protected]0d31fbc2013-05-28 17:00:37351 GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
[email protected]854e1312012-07-30 17:26:30352 CheckTitleTest(url, "set cookie on unload");
[email protected]b83fbfe82012-04-21 00:05:07353
354 // Navigate to a cross-site page that loads immediately without making a
355 // network request. The unload event should still be run.
Alex Moshchuk765684f52019-09-21 01:16:41356 EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
[email protected]b83fbfe82012-04-21 00:05:07357
358 // Check that the cookie was set.
359 EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
360}
361
[email protected]0d31fbc2013-05-28 17:00:37362namespace {
363
364// Handles |request| by serving a redirect response.
dcheng40ce7b382016-04-08 23:46:13365std::unique_ptr<net::test_server::HttpResponse> NoContentResponseHandler(
[email protected]0d31fbc2013-05-28 17:00:37366 const std::string& path,
367 const net::test_server::HttpRequest& request) {
brettw94a2cc22015-07-01 19:26:54368 if (!base::StartsWith(path, request.relative_url,
Lei Zhangdf291f62021-04-14 17:23:44369 base::CompareCase::SENSITIVE)) {
370 return nullptr;
371 }
[email protected]0d31fbc2013-05-28 17:00:37372
dcheng40ce7b382016-04-08 23:46:13373 std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
[email protected]0d31fbc2013-05-28 17:00:37374 new net::test_server::BasicHttpResponse);
[email protected]c1dffe82013-06-26 20:59:05375 http_response->set_code(net::HTTP_NO_CONTENT);
dcheng36b6aec92015-12-26 06:16:36376 return std::move(http_response);
[email protected]0d31fbc2013-05-28 17:00:37377}
378
379} // namespace
380
[email protected]b83fbfe82012-04-21 00:05:07381// Tests that the unload handler is not run for 204 responses.
382// If this flakes use http://crbug.com/80596.
John Abd-El-Malek6883212992018-04-25 22:32:22383IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteNoUnloadOn204) {
martijn64a51112016-11-14 23:24:12384 const char kNoContentPath[] = "/nocontent";
385 embedded_test_server()->RegisterRequestHandler(
Makoto Shimazu833e1c72019-10-09 21:14:50386 base::BindRepeating(&NoContentResponseHandler, kNoContentPath));
martijn64a51112016-11-14 23:24:12387
svaldezc3a9a172015-11-03 22:01:33388 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]b83fbfe82012-04-21 00:05:07389
390 // Start with a URL that sets a cookie in its unload handler.
[email protected]0d31fbc2013-05-28 17:00:37391 GURL url = embedded_test_server()->GetURL("/onunload_cookie.html");
[email protected]854e1312012-07-30 17:26:30392 CheckTitleTest(url, "set cookie on unload");
[email protected]b83fbfe82012-04-21 00:05:07393
394 // Navigate to a cross-site URL that returns a 204 No Content response.
Alex Moshchuk765684f52019-09-21 01:16:41395 EXPECT_TRUE(NavigateToURLAndExpectNoCommit(
396 shell(), embedded_test_server()->GetURL(kNoContentPath)));
[email protected]b83fbfe82012-04-21 00:05:07397
398 // Check that the unload cookie was not set.
399 EXPECT_EQ("", GetCookies(url));
400}
401
[email protected]b83fbfe82012-04-21 00:05:07402// Tests that the onbeforeunload and onunload logic is short-circuited if the
403// old renderer is gone. In that case, we don't want to wait for the old
404// renderer to run the handlers.
405// We need to disable this on Mac because the crash causes the OS CrashReporter
406// process to kick in to analyze the poor dead renderer. Unfortunately, if the
407// app isn't stripped of debug symbols, this takes about five minutes to
408// complete and isn't conducive to quick turnarounds. As we don't currently
409// strip the app on the build bots, this is bad times.
Xiaohan Wangbf7702b92022-01-15 14:34:20410#if BUILDFLAG(IS_MAC)
johnme6e0c4eab2015-07-01 16:24:04411#define MAYBE_CrossSiteAfterCrash DISABLED_CrossSiteAfterCrash
412#else
413#define MAYBE_CrossSiteAfterCrash CrossSiteAfterCrash
414#endif
John Abd-El-Malek6883212992018-04-25 22:32:22415IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, MAYBE_CrossSiteAfterCrash) {
[email protected]c02f1ba2014-02-03 06:53:53416 // Make sure we have a live process before trying to kill it.
Alex Moshchuk765684f52019-09-21 01:16:41417 EXPECT_TRUE(NavigateToURL(shell(), GURL("about:blank")));
[email protected]c02f1ba2014-02-03 06:53:53418
[email protected]b83fbfe82012-04-21 00:05:07419 // Cause the renderer to crash.
[email protected]8ffad4e2014-01-02 23:18:26420 RenderProcessHostWatcher crash_observer(
421 shell()->web_contents(),
422 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
Gyuyoung Kim107c2a02021-04-13 01:49:30423 EXPECT_FALSE(NavigateToURL(shell(), GURL(blink::kChromeUICrashURL)));
[email protected]b83fbfe82012-04-21 00:05:07424 // Wait for browser to notice the renderer crash.
425 crash_observer.Wait();
426
427 // Navigate to a new cross-site page. The browser should not wait around for
428 // the old renderer's on{before}unload handlers to run.
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43429 ASSERT_TRUE(embedded_test_server()->Start());
430 GURL url(embedded_test_server()->GetURL("/content-sniffer-test0.html"));
431 CheckTitleTest(url, "Content Sniffer Test 0");
[email protected]b83fbfe82012-04-21 00:05:07432}
[email protected]b83fbfe82012-04-21 00:05:07433
434// Tests that cross-site navigations work when the new page does not go through
435// the BufferedEventHandler (e.g., non-http{s} URLs). (Bug 1225872)
John Abd-El-Malek6883212992018-04-25 22:32:22436IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteNavigationNonBuffered) {
[email protected]b83fbfe82012-04-21 00:05:07437 // Start with an HTTP page.
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43438 ASSERT_TRUE(embedded_test_server()->Start());
439 GURL url1(embedded_test_server()->GetURL("/content-sniffer-test0.html"));
440 CheckTitleTest(url1, "Content Sniffer Test 0");
[email protected]b83fbfe82012-04-21 00:05:07441
442 // Now load a file:// page, which does not use the BufferedEventHandler.
443 // Make sure that the page loads and displays a title, and doesn't get stuck.
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43444 GURL url2 = GetTestUrl("", "title2.html");
445 CheckTitleTest(url2, "Title Of Awesomeness");
[email protected]b83fbfe82012-04-21 00:05:07446}
447
benwells13a1ded92014-11-04 03:41:29448// Flaky everywhere. http://crbug.com/130404
[email protected]b83fbfe82012-04-21 00:05:07449// Tests that a cross-site navigation to an error page (resulting in the link
450// doctor page) still runs the onunload handler and can support navigations
451// away from the link doctor page. (Bug 1235537)
John Abd-El-Malek6883212992018-04-25 22:32:22452IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
benwells13a1ded92014-11-04 03:41:29453 DISABLED_CrossSiteNavigationErrorPage) {
svaldezc3a9a172015-11-03 22:01:33454 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]b83fbfe82012-04-21 00:05:07455
[email protected]0d31fbc2013-05-28 17:00:37456 GURL url(embedded_test_server()->GetURL("/onunload_cookie.html"));
[email protected]854e1312012-07-30 17:26:30457 CheckTitleTest(url, "set cookie on unload");
[email protected]b83fbfe82012-04-21 00:05:07458
[email protected]854e1312012-07-30 17:26:30459 // Navigate to a new cross-site URL that results in an error.
[email protected]b83fbfe82012-04-21 00:05:07460 // TODO(creis): If this causes crashes or hangs, it might be for the same
461 // reason as ErrorPageTest::DNSError. See bug 1199491 and
462 // http://crbug.com/22877.
Alex Moshchuk765684f52019-09-21 01:16:41463 GURL failed_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
464 std::unique_ptr<URLLoaderInterceptor> url_interceptor =
465 URLLoaderInterceptor::SetupRequestFailForURL(failed_url,
466 net::ERR_NAME_NOT_RESOLVED);
467 EXPECT_FALSE(NavigateToURL(shell(), failed_url));
[email protected]b83fbfe82012-04-21 00:05:07468
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02469 EXPECT_NE(u"set cookie on unload", shell()->web_contents()->GetTitle());
[email protected]b83fbfe82012-04-21 00:05:07470
471 // Check that the cookie was set, meaning that the onunload handler ran.
472 EXPECT_EQ("onunloadCookie=foo", GetCookies(url));
473
474 // Check that renderer-initiated navigations still work. In a previous bug,
475 // the ResourceDispatcherHost would think that such navigations were
476 // cross-site, because we didn't clean up from the previous request. Since
477 // WebContentsImpl was in the NORMAL state, it would ignore the attempt to run
478 // the onunload handler, and the navigation would fail. We can't test by
479 // redirecting to javascript:window.location='someURL', since javascript:
480 // URLs are prohibited by policy from interacting with sensitive chrome
481 // pages of which the error page is one. Instead, use automation to kick
482 // off the navigation, and wait to see that the tab loads.
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02483 std::u16string expected_title16(u"Title Of Awesomeness");
[email protected]854e1312012-07-30 17:26:30484 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
[email protected]b83fbfe82012-04-21 00:05:07485
[email protected]0d31fbc2013-05-28 17:00:37486 GURL test_url(embedded_test_server()->GetURL("/title2.html"));
Avi Drissmanc91bd8e2021-04-19 23:58:44487 std::string redirect_script =
488 "window.location='" + test_url.possibly_invalid_spec() + "';" + "true;";
489 EXPECT_EQ(true, EvalJs(shell(), redirect_script));
[email protected]b83fbfe82012-04-21 00:05:07490 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
491}
492
John Abd-El-Malek6883212992018-04-25 22:32:22493IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteNavigationErrorPage2) {
svaldezc3a9a172015-11-03 22:01:33494 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]c47329d2012-07-09 20:00:25495
[email protected]0d31fbc2013-05-28 17:00:37496 GURL url(embedded_test_server()->GetURL("/title2.html"));
[email protected]854e1312012-07-30 17:26:30497 CheckTitleTest(url, "Title Of Awesomeness");
[email protected]c47329d2012-07-09 20:00:25498
[email protected]854e1312012-07-30 17:26:30499 // Navigate to a new cross-site URL that results in an error.
[email protected]c47329d2012-07-09 20:00:25500 // TODO(creis): If this causes crashes or hangs, it might be for the same
501 // reason as ErrorPageTest::DNSError. See bug 1199491 and
502 // http://crbug.com/22877.
Alex Moshchuk765684f52019-09-21 01:16:41503 GURL failed_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
504 std::unique_ptr<URLLoaderInterceptor> url_interceptor =
505 URLLoaderInterceptor::SetupRequestFailForURL(failed_url,
506 net::ERR_NAME_NOT_RESOLVED);
[email protected]c47329d2012-07-09 20:00:25507
Alex Moshchuk765684f52019-09-21 01:16:41508 EXPECT_FALSE(NavigateToURL(shell(), failed_url));
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02509 EXPECT_NE(u"Title Of Awesomeness", shell()->web_contents()->GetTitle());
[email protected]c47329d2012-07-09 20:00:25510
511 // Repeat navigation. We are testing that this completes.
Alex Moshchuk765684f52019-09-21 01:16:41512 EXPECT_FALSE(NavigateToURL(shell(), failed_url));
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02513 EXPECT_NE(u"Title Of Awesomeness", shell()->web_contents()->GetTitle());
[email protected]c47329d2012-07-09 20:00:25514}
515
John Abd-El-Malek6883212992018-04-25 22:32:22516IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossOriginRedirectBlocked) {
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43517 ASSERT_TRUE(embedded_test_server()->Start());
518 GURL url(
519 embedded_test_server()->GetURL("/cross-origin-redirect-blocked.html"));
[email protected]b83fbfe82012-04-21 00:05:07520 // We expect the following URL requests from this test:
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43521 // 1- navigation to http://127.0.0.1:[port]/cross-origin-redirect-blocked.html
522 // 2- XHR to
523 // http://127.0.0.1:[port]/server-redirect-302?http://a.com:[port]/title2.html
524 // 3- above XHR is redirected to http://a.com:[port]/title2.html which should
525 // be blocked
526 // 4- When the page notices the above request is blocked, it issues an XHR to
527 // http://127.0.0.1:[port]/title2.html
528 // 5- When the above XHR succeed, the page navigates to
529 // http://127.0.0.1:[port]/title3.html
[email protected]b83fbfe82012-04-21 00:05:07530 //
John Abd-El-Malek7e8aa6ab2018-04-25 20:21:43531 // If the redirect in #3 were not blocked, we'd instead see a navigation
532 // to http://a.com[port]/title2.html, and the title would be different.
533 CheckTitleTest(url, "Title Of More Awesomeness");
[email protected]b83fbfe82012-04-21 00:05:07534}
535
536// Tests that ResourceRequestInfoImpl is updated correctly on failed
537// requests, to prevent calling Read on a request that has already failed.
538// See bug 40250.
John Abd-El-Malek6883212992018-04-25 22:32:22539IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CrossSiteFailedRequest) {
[email protected]b83fbfe82012-04-21 00:05:07540 // Visit another URL first to trigger a cross-site navigation.
Alex Moshchuk765684f52019-09-21 01:16:41541 EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "simple_page.html")));
[email protected]b83fbfe82012-04-21 00:05:07542
543 // Visit a URL that fails without calling ResourceDispatcherHost::Read.
544 GURL broken_url("chrome://theme");
Alex Moshchuk765684f52019-09-21 01:16:41545 EXPECT_FALSE(NavigateToURL(shell(), broken_url));
[email protected]b83fbfe82012-04-21 00:05:07546}
[email protected]854e1312012-07-30 17:26:30547
[email protected]fbaccee2013-08-12 23:24:02548namespace {
549
dcheng40ce7b382016-04-08 23:46:13550std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
[email protected]fbaccee2013-08-12 23:24:02551 const std::string& request_path,
552 const net::test_server::HttpRequest& request) {
brettw94a2cc22015-07-01 19:26:54553 if (!base::StartsWith(request.relative_url, request_path,
Lei Zhangdf291f62021-04-14 17:23:44554 base::CompareCase::SENSITIVE)) {
555 return nullptr;
556 }
[email protected]fbaccee2013-08-12 23:24:02557
dcheng40ce7b382016-04-08 23:46:13558 std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
[email protected]fbaccee2013-08-12 23:24:02559 new net::test_server::BasicHttpResponse);
560 http_response->set_code(net::HTTP_FOUND);
561 http_response->AddCustomHeader(
562 "Location", request.relative_url.substr(request_path.length()));
dcheng36b6aec92015-12-26 06:16:36563 return std::move(http_response);
[email protected]fbaccee2013-08-12 23:24:02564}
565
566} // namespace
567
568// Test that we update the cookie policy URLs correctly when transferring
569// navigations.
John Abd-El-Malek6883212992018-04-25 22:32:22570IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, CookiePolicy) {
[email protected]fbaccee2013-08-12 23:24:02571 embedded_test_server()->RegisterRequestHandler(
Makoto Shimazu833e1c72019-10-09 21:14:50572 base::BindRepeating(&HandleRedirectRequest, "/redirect?"));
martijn64a51112016-11-14 23:24:12573 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]fbaccee2013-08-12 23:24:02574
575 std::string set_cookie_url(base::StringPrintf(
pkastingcba13292014-11-20 03:35:21576 "http://localhost:%u/set_cookie.html", embedded_test_server()->port()));
[email protected]fbaccee2013-08-12 23:24:02577 GURL url(embedded_test_server()->GetURL("/redirect?" + set_cookie_url));
578
Jan Wilken Dörrie8aeb5742021-03-23 19:27:02579 std::u16string expected_title16(u"cookie set");
Alex Moshchuk765684f52019-09-21 01:16:41580 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
581 EXPECT_TRUE(NavigateToURL(shell(), url,
582 GURL(set_cookie_url) /* expected_commit_url */));
583 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
[email protected]fbaccee2013-08-12 23:24:02584}
585
ohrn19893e62014-11-17 16:00:01586// Test that ui::PAGE_TRANSITION_CLIENT_REDIRECT is correctly set
587// when encountering a meta refresh tag.
John Abd-El-Malek6883212992018-04-25 22:32:22588IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, PageTransitionClientRedirect) {
svaldezc3a9a172015-11-03 22:01:33589 ASSERT_TRUE(embedded_test_server()->Start());
ohrn19893e62014-11-17 16:00:01590
ohrn19893e62014-11-17 16:00:01591 NavigateToURLBlockUntilNavigationsComplete(
Thanh Le006f25322017-09-13 17:38:04592 shell(), embedded_test_server()->GetURL("/client_redirect.html"), 2);
ohrn19893e62014-11-17 16:00:01593
John Abd-El-Malekff2fb3d12019-07-29 06:32:12594 NavigationEntry* entry =
595 shell()->web_contents()->GetController().GetLastCommittedEntry();
596
597 EXPECT_TRUE(entry->GetTransitionType() & ui::PAGE_TRANSITION_CLIENT_REDIRECT);
ohrn19893e62014-11-17 16:00:01598}
599
Clark DuVallb2680c22018-08-10 15:27:27600IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SubresourceRedirectToDataURLBlocked) {
601 ASSERT_TRUE(embedded_test_server()->Start());
602
603 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
604
605 GURL subresource_url = embedded_test_server()->GetURL(
606 "/server-redirect?data:text/plain,redirected1");
607 std::string script = R"((url => {
608 var xhr = new XMLHttpRequest();
609 xhr.open('GET', url, true);
Chris Fredricksonb854bbf2023-03-27 17:27:44610 return new Promise(resolve => {
611 xhr.onload = () => resolve("ALLOWED");
612 xhr.onerror = () => resolve("BLOCKED");
613 xhr.send();
614 });
Clark DuVallb2680c22018-08-10 15:27:27615 }))";
Clark DuVallb2680c22018-08-10 15:27:27616
Avi Drissmanc91bd8e2021-04-19 23:58:44617 EXPECT_EQ("BLOCKED",
Chris Fredricksonb854bbf2023-03-27 17:27:44618 EvalJs(shell(), script + "('" + subresource_url.spec() + "')"));
Clark DuVallb2680c22018-08-10 15:27:27619}
620
621IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RedirectToDataURLBlocked) {
622 ASSERT_TRUE(embedded_test_server()->Start());
623 EXPECT_FALSE(NavigateToURL(
624 shell(), embedded_test_server()->GetURL(
625 "/server-redirect?data:text/plain,redirected1")));
626}
627
Clark DuValle5581582018-10-11 22:02:26628IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RedirectToAboutURLBlocked) {
629 ASSERT_TRUE(embedded_test_server()->Start());
630 EXPECT_FALSE(NavigateToURL(
631 shell(), embedded_test_server()->GetURL(
632 "/server-redirect?" + std::string(url::kAboutBlankURL))));
633}
634
Clark DuVallb2680c22018-08-10 15:27:27635namespace {
636
637// Creates a valid filesystem URL.
638GURL CreateFileSystemURL(Shell* window) {
Avi Drissmanc91bd8e2021-04-19 23:58:44639 std::string filesystem_url_string = EvalJs(window, R"(
Clark DuVallb2680c22018-08-10 15:27:27640 var blob = new Blob(['<html><body>hello</body></html>'],
641 {type: 'text/html'});
Chris Fredricksonb854bbf2023-03-27 17:27:44642 new Promise(resolve => {
643 window.webkitRequestFileSystem(TEMPORARY, blob.size, fs => {
644 fs.root.getFile('foo.html', {create: true}, file => {
645 file.createWriter(writer => {
646 writer.write(blob);
647 writer.onwriteend = () => {
648 resolve(file.toURL());
649 }
650 });
Clark DuVallb2680c22018-08-10 15:27:27651 });
652 });
Chris Fredricksonb854bbf2023-03-27 17:27:44653 });)")
Avi Drissmanc91bd8e2021-04-19 23:58:44654 .ExtractString();
Clark DuVallb2680c22018-08-10 15:27:27655 GURL filesystem_url(filesystem_url_string);
656 EXPECT_TRUE(filesystem_url.is_valid());
657 EXPECT_TRUE(filesystem_url.SchemeIsFileSystem());
658 return filesystem_url;
659}
660
661} // namespace
662
663IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
664 SubresourceRedirectToFileSystemURLBlocked) {
665 ASSERT_TRUE(embedded_test_server()->Start());
666
667 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
668
669 GURL subresource_url = embedded_test_server()->GetURL(
670 "/server-redirect?" + CreateFileSystemURL(shell()).spec());
671 std::string script = R"((url => {
672 var xhr = new XMLHttpRequest();
673 xhr.open('GET', url, true);
Chris Fredricksonb854bbf2023-03-27 17:27:44674 return new Promise(resolve => {
675 xhr.onload = () => resolve("ALLOWED");
676 xhr.onerror = () => resolve("BLOCKED");
677 xhr.send();
678 });
Clark DuVallb2680c22018-08-10 15:27:27679 }))";
Clark DuVallb2680c22018-08-10 15:27:27680
Avi Drissmanc91bd8e2021-04-19 23:58:44681 EXPECT_EQ("BLOCKED",
Chris Fredricksonb854bbf2023-03-27 17:27:44682 EvalJs(shell(), script + "('" + subresource_url.spec() + "')"));
Clark DuVallb2680c22018-08-10 15:27:27683}
684
685IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, RedirectToFileSystemURLBlocked) {
686 ASSERT_TRUE(embedded_test_server()->Start());
687 // Need to navigate to a URL first so the filesystem can be created.
688 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL("/echo")));
689
690 EXPECT_FALSE(NavigateToURL(
691 shell(), embedded_test_server()->GetURL(
692 "/server-redirect?" + CreateFileSystemURL(shell()).spec())));
693}
694
mkwstb1d1a952016-06-22 14:58:05695namespace {
696
John Abd-El-Malek2d2173732018-04-25 13:40:51697struct RequestData {
mkwstb1d1a952016-06-22 14:58:05698 const GURL url;
Maks Orlovich5d02d9e02019-12-15 22:14:10699 const net::SiteForCookies site_for_cookies;
Arthur Sonzognic686e8f2024-01-11 08:36:37700 const std::optional<url::Origin> initiator;
Benoit Lize0a370db72017-08-28 17:01:29701 const int load_flags;
702 const std::string referrer;
mkwstb1d1a952016-06-22 14:58:05703
John Abd-El-Malek2d2173732018-04-25 13:40:51704 RequestData(const GURL& url,
Maks Orlovich5d02d9e02019-12-15 22:14:10705 const net::SiteForCookies& site_for_cookies,
Arthur Sonzognic686e8f2024-01-11 08:36:37706 const std::optional<url::Origin>& initiator,
John Abd-El-Malek2d2173732018-04-25 13:40:51707 int load_flags,
708 const std::string& referrer)
Benoit Lize0a370db72017-08-28 17:01:29709 : url(url),
Maks Orlovich5d02d9e02019-12-15 22:14:10710 site_for_cookies(site_for_cookies),
Benoit Lize0a370db72017-08-28 17:01:29711 initiator(initiator),
712 load_flags(load_flags),
713 referrer(referrer) {}
mkwstb1d1a952016-06-22 14:58:05714};
715
mkwstb1d1a952016-06-22 14:58:05716} // namespace
717
John Abd-El-Malek2d2173732018-04-25 13:40:51718class RequestDataBrowserTest : public ContentBrowserTest {
mkwstb1d1a952016-06-22 14:58:05719 public:
John Abd-El-Malek2d2173732018-04-25 13:40:51720 RequestDataBrowserTest()
721 : interceptor_(std::make_unique<content::URLLoaderInterceptor>(
722 base::BindRepeating(&RequestDataBrowserTest::OnRequest,
723 base::Unretained(this)))) {}
724 ~RequestDataBrowserTest() override {}
mkwstb1d1a952016-06-22 14:58:05725
John Abd-El-Malek2d2173732018-04-25 13:40:51726 std::vector<RequestData> data() {
727 base::AutoLock auto_lock(requests_lock_);
728 auto copy = requests_;
729 return copy;
730 }
731
John Abd-El-Malekb95feaa2018-06-12 17:50:35732 void WaitForRequests(size_t count) {
733 while (true) {
734 base::RunLoop run_loop;
735 {
736 base::AutoLock auto_lock(requests_lock_);
Solomon Kinardab293bae2024-09-19 17:13:51737 if (requests_.size() == count) {
John Abd-El-Malekb95feaa2018-06-12 17:50:35738 return;
Solomon Kinardab293bae2024-09-19 17:13:51739 }
John Abd-El-Malekb95feaa2018-06-12 17:50:35740 requests_closure_ = run_loop.QuitClosure();
741 }
742 run_loop.Run();
743 }
744 }
745
John Abd-El-Malek2d2173732018-04-25 13:40:51746 private:
mkwstb1d1a952016-06-22 14:58:05747 void SetUpOnMainThread() override {
748 ContentBrowserTest::SetUpOnMainThread();
749
750 ASSERT_TRUE(embedded_test_server()->Start());
751
jam8f34ea72017-04-26 17:48:55752 host_resolver()->AddRule("*", "127.0.0.1");
mkwstb1d1a952016-06-22 14:58:05753 }
754
John Abd-El-Malek2d2173732018-04-25 13:40:51755 void TearDownOnMainThread() override { interceptor_.reset(); }
756
757 bool OnRequest(URLLoaderInterceptor::RequestParams* params) {
758 RequestCreated(RequestData(
759 params->url_request.url, params->url_request.site_for_cookies,
760 params->url_request.request_initiator, params->url_request.load_flags,
761 params->url_request.referrer.spec()));
762 return false;
763 }
764
765 void RequestCreated(RequestData data) {
766 base::AutoLock auto_lock(requests_lock_);
767 requests_.push_back(data);
Solomon Kinardab293bae2024-09-19 17:13:51768 if (requests_closure_) {
danakjf4b9e942019-11-29 15:43:04769 std::move(requests_closure_).Run();
Solomon Kinardab293bae2024-09-19 17:13:51770 }
John Abd-El-Malek2d2173732018-04-25 13:40:51771 }
772
773 base::Lock requests_lock_;
774 std::vector<RequestData> requests_;
danakjf4b9e942019-11-29 15:43:04775 base::OnceClosure requests_closure_;
John Abd-El-Malek2d2173732018-04-25 13:40:51776 std::unique_ptr<URLLoaderInterceptor> interceptor_;
mkwstb1d1a952016-06-22 14:58:05777};
778
Tsuyoshi Horo59aea792023-05-24 05:21:43779IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, Basic) {
mkwst47673cd2016-07-14 09:48:58780 GURL top_url(embedded_test_server()->GetURL("/page_with_subresources.html"));
Daniel Cheng88186bd52017-10-20 08:14:46781 url::Origin top_origin = url::Origin::Create(top_url);
mkwstb1d1a952016-06-22 14:58:05782
783 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
Tsuyoshi Horo18ae3602023-05-23 03:26:09784 WaitForRequests(8u);
mkwstb1d1a952016-06-22 14:58:05785
John Abd-El-Malek2d2173732018-04-25 13:40:51786 auto requests = data();
787 EXPECT_EQ(8u, requests.size());
mkwstb1d1a952016-06-22 14:58:05788
arthursonzogni224aa612017-12-07 15:31:51789 // All resources loaded directly by the top-level document should have a
790 // |first_party| and |initiator| that match the URL of the top-level document.
791 // The top-level document itself doesn't have an |initiator|.
John Abd-El-Malek2d2173732018-04-25 13:40:51792 const RequestData* first_request = &requests[0];
Maks Orlovich5d02d9e02019-12-15 22:14:10793 EXPECT_TRUE(first_request->site_for_cookies.IsEquivalent(
794 net::SiteForCookies::FromUrl(top_url)));
arthursonzogni224aa612017-12-07 15:31:51795 EXPECT_FALSE(first_request->initiator.has_value());
John Abd-El-Malek2d2173732018-04-25 13:40:51796 for (size_t i = 1; i < requests.size(); i++) {
797 const RequestData* request = &requests[i];
Maks Orlovich5d02d9e02019-12-15 22:14:10798 EXPECT_TRUE(request->site_for_cookies.IsEquivalent(
799 net::SiteForCookies::FromOrigin(top_origin)));
arthursonzogni224aa612017-12-07 15:31:51800 ASSERT_TRUE(request->initiator.has_value());
801 EXPECT_EQ(top_origin, request->initiator);
mkwst47673cd2016-07-14 09:48:58802 }
803}
804
John Abd-El-Malek2d2173732018-04-25 13:40:51805IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, LinkRelPrefetch) {
Benoit Lize0a370db72017-08-28 17:01:29806 GURL top_url(embedded_test_server()->GetURL("/link_rel_prefetch.html"));
Daniel Cheng88186bd52017-10-20 08:14:46807 url::Origin top_origin = url::Origin::Create(top_url);
Benoit Lize0a370db72017-08-28 17:01:29808
809 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
John Abd-El-Malekb95feaa2018-06-12 17:50:35810 WaitForRequests(2u);
Benoit Lize0a370db72017-08-28 17:01:29811
John Abd-El-Malek2d2173732018-04-25 13:40:51812 auto requests = data();
813 EXPECT_EQ(2u, requests.size());
814 auto* request = &requests[1];
Benoit Lize0a370db72017-08-28 17:01:29815 EXPECT_EQ(top_origin, request->initiator);
816 EXPECT_EQ(top_url, request->referrer);
817 EXPECT_TRUE(request->load_flags & net::LOAD_PREFETCH);
818}
819
John Abd-El-Malek2d2173732018-04-25 13:40:51820IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, LinkRelPrefetchReferrerPolicy) {
Benoit Lize0a370db72017-08-28 17:01:29821 GURL top_url(embedded_test_server()->GetURL(
822 "/link_rel_prefetch_referrer_policy.html"));
arthursonzogni224aa612017-12-07 15:31:51823 GURL img_url(embedded_test_server()->GetURL("/image.jpg"));
Daniel Cheng88186bd52017-10-20 08:14:46824 url::Origin top_origin = url::Origin::Create(top_url);
Benoit Lize0a370db72017-08-28 17:01:29825
826 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
John Abd-El-Malekb95feaa2018-06-12 17:50:35827 WaitForRequests(2u);
Benoit Lize0a370db72017-08-28 17:01:29828
John Abd-El-Malek2d2173732018-04-25 13:40:51829 auto requests = data();
830 EXPECT_EQ(2u, requests.size());
831 auto* main_frame_request = &requests[0];
832 auto* image_request = &requests[1];
arthursonzogni224aa612017-12-07 15:31:51833
834 // Check the main frame request.
835 EXPECT_EQ(top_url, main_frame_request->url);
836 EXPECT_FALSE(main_frame_request->initiator.has_value());
837
838 // Check the image request.
839 EXPECT_EQ(img_url, image_request->url);
840 EXPECT_TRUE(image_request->initiator.has_value());
841 EXPECT_EQ(top_origin, image_request->initiator);
Benoit Lize0a370db72017-08-28 17:01:29842 // Respect the "origin" policy set by the <meta> tag.
Mike West800532c2021-10-14 09:26:52843 EXPECT_EQ(top_url.DeprecatedGetOriginAsURL().spec(), image_request->referrer);
arthursonzogni224aa612017-12-07 15:31:51844 EXPECT_TRUE(image_request->load_flags & net::LOAD_PREFETCH);
Benoit Lize0a370db72017-08-28 17:01:29845}
846
Alison Gale81f4f2c72024-04-22 19:33:31847// TODO(crbug.com/40805845): Flaky on all platforms.
Dale Curtisaa354112021-11-19 23:30:53848IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, DISABLED_BasicCrossSite) {
mkwst47673cd2016-07-14 09:48:58849 GURL top_url(embedded_test_server()->GetURL(
850 "a.com", "/nested_page_with_subresources.html"));
851 GURL nested_url(embedded_test_server()->GetURL(
852 "not-a.com", "/page_with_subresources.html"));
Daniel Cheng88186bd52017-10-20 08:14:46853 url::Origin top_origin = url::Origin::Create(top_url);
854 url::Origin nested_origin = url::Origin::Create(nested_url);
mkwst47673cd2016-07-14 09:48:58855
856 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
857
John Abd-El-Malek2d2173732018-04-25 13:40:51858 auto requests = data();
859 EXPECT_EQ(9u, requests.size());
mkwst47673cd2016-07-14 09:48:58860
861 // The first items loaded are the top-level and nested documents. These should
Maks Orlovich5d02d9e02019-12-15 22:14:10862 // both have a |site_for_cookies| that matches the origin of the top-level
863 // document. The top-level document has no initiator and the nested frame is
864 // initiated by the top-level document.
John Abd-El-Malek2d2173732018-04-25 13:40:51865 EXPECT_EQ(top_url, requests[0].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10866 EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
867 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51868 EXPECT_FALSE(requests[0].initiator.has_value());
mkwst47673cd2016-07-14 09:48:58869
John Abd-El-Malek2d2173732018-04-25 13:40:51870 EXPECT_EQ(nested_url, requests[1].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10871 EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
872 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51873 EXPECT_EQ(top_origin, requests[1].initiator);
mkwst47673cd2016-07-14 09:48:58874
875 // The remaining items are loaded as subresources in the nested document, and
876 // should have a unique first-party, and an initiator that matches the
877 // document in which they're embedded.
John Abd-El-Malek2d2173732018-04-25 13:40:51878 for (size_t i = 2; i < requests.size(); i++) {
879 SCOPED_TRACE(requests[i].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10880 EXPECT_TRUE(requests[i].site_for_cookies.IsNull());
John Abd-El-Malek2d2173732018-04-25 13:40:51881 EXPECT_EQ(nested_origin, requests[i].initiator);
mkwst47673cd2016-07-14 09:48:58882 }
mkwstb1d1a952016-06-22 14:58:05883}
884
John Abd-El-Malek2d2173732018-04-25 13:40:51885IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, SameOriginNested) {
mkwstb1d1a952016-06-22 14:58:05886 GURL top_url(embedded_test_server()->GetURL("/page_with_iframe.html"));
887 GURL image_url(embedded_test_server()->GetURL("/image.jpg"));
888 GURL nested_url(embedded_test_server()->GetURL("/title1.html"));
Daniel Cheng88186bd52017-10-20 08:14:46889 url::Origin top_origin = url::Origin::Create(top_url);
mkwstb1d1a952016-06-22 14:58:05890
891 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
Tsuyoshi Horo18ae3602023-05-23 03:26:09892 WaitForRequests(3u);
mkwstb1d1a952016-06-22 14:58:05893
John Abd-El-Malek2d2173732018-04-25 13:40:51894 auto requests = data();
895 EXPECT_EQ(3u, requests.size());
mkwstb1d1a952016-06-22 14:58:05896
arthursonzogni224aa612017-12-07 15:31:51897 // User-initiated top-level navigations have a first-party that matches the
898 // URL to which they navigate. The navigation was initiated outside of a
899 // document, so there is no |initiator|.
John Abd-El-Malek2d2173732018-04-25 13:40:51900 EXPECT_EQ(top_url, requests[0].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10901 EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
902 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51903 EXPECT_FALSE(requests[0].initiator.has_value());
mkwstb1d1a952016-06-22 14:58:05904
905 // Subresource requests have a first-party and initiator that matches the
906 // document in which they're embedded.
John Abd-El-Malek2d2173732018-04-25 13:40:51907 EXPECT_EQ(image_url, requests[1].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10908 EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
909 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51910 EXPECT_EQ(top_origin, requests[1].initiator);
mkwstb1d1a952016-06-22 14:58:05911
912 // Same-origin nested frames have a first-party and initiator that matches
Maks Orlovich5d02d9e02019-12-15 22:14:10913 // the document in which they're embedded (since the frame is same site with
914 // toplevel).
John Abd-El-Malek2d2173732018-04-25 13:40:51915 EXPECT_EQ(nested_url, requests[2].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10916 EXPECT_TRUE(requests[2].site_for_cookies.IsEquivalent(
917 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51918 EXPECT_EQ(top_origin, requests[2].initiator);
mkwstb1d1a952016-06-22 14:58:05919}
920
John Abd-El-Malek2d2173732018-04-25 13:40:51921IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, SameOriginAuxiliary) {
mkwstb1d1a952016-06-22 14:58:05922 GURL top_url(embedded_test_server()->GetURL("/simple_links.html"));
923 GURL auxiliary_url(embedded_test_server()->GetURL("/title2.html"));
Daniel Cheng88186bd52017-10-20 08:14:46924 url::Origin top_origin = url::Origin::Create(top_url);
mkwstb1d1a952016-06-22 14:58:05925
926 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
927
928 ShellAddedObserver new_shell_observer;
Avi Drissmanc91bd8e2021-04-19 23:58:44929 EXPECT_EQ(true, EvalJs(shell(), "clickSameSiteNewWindowLink();"));
mkwstb1d1a952016-06-22 14:58:05930 Shell* new_shell = new_shell_observer.GetShell();
Fergal Dalyf0522332020-07-18 06:09:46931 EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));
Tsuyoshi Horo18ae3602023-05-23 03:26:09932 WaitForRequests(2u);
mkwstb1d1a952016-06-22 14:58:05933
John Abd-El-Malek2d2173732018-04-25 13:40:51934 auto requests = data();
935 EXPECT_EQ(2u, requests.size());
mkwstb1d1a952016-06-22 14:58:05936
arthursonzogni224aa612017-12-07 15:31:51937 // User-initiated top-level navigations have a first-party that matches the
938 // URL to which they navigate, even if they fail to load. The navigation was
939 // initiated outside of a document, so there is no |initiator|.
John Abd-El-Malek2d2173732018-04-25 13:40:51940 EXPECT_EQ(top_url, requests[0].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10941 EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
942 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51943 EXPECT_FALSE(requests[0].initiator.has_value());
mkwstb1d1a952016-06-22 14:58:05944
945 // Auxiliary navigations have a first-party that matches the URL to which they
946 // navigate, and an initiator that matches the document that triggered them.
John Abd-El-Malek2d2173732018-04-25 13:40:51947 EXPECT_EQ(auxiliary_url, requests[1].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10948 EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
949 net::SiteForCookies::FromUrl(auxiliary_url)));
John Abd-El-Malek2d2173732018-04-25 13:40:51950 EXPECT_EQ(top_origin, requests[1].initiator);
mkwstb1d1a952016-06-22 14:58:05951}
952
John Abd-El-Malek2d2173732018-04-25 13:40:51953IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, CrossOriginAuxiliary) {
mkwstb1d1a952016-06-22 14:58:05954 GURL top_url(embedded_test_server()->GetURL("/simple_links.html"));
955 GURL auxiliary_url(embedded_test_server()->GetURL("foo.com", "/title2.html"));
Daniel Cheng88186bd52017-10-20 08:14:46956 url::Origin top_origin = url::Origin::Create(top_url);
mkwstb1d1a952016-06-22 14:58:05957
958 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
959
Avi Drissmanc91bd8e2021-04-19 23:58:44960 const char kReplacePortNumber[] = "setPortNumber(%d);";
mkwstb1d1a952016-06-22 14:58:05961 uint16_t port_number = embedded_test_server()->port();
Avi Drissmanc91bd8e2021-04-19 23:58:44962 EXPECT_TRUE(
963 ExecJs(shell(), base::StringPrintf(kReplacePortNumber, port_number)));
mkwstb1d1a952016-06-22 14:58:05964
965 ShellAddedObserver new_shell_observer;
Avi Drissmanc91bd8e2021-04-19 23:58:44966 EXPECT_EQ(true, EvalJs(shell(), "clickCrossSiteNewWindowLink();"));
mkwstb1d1a952016-06-22 14:58:05967 Shell* new_shell = new_shell_observer.GetShell();
Fergal Dalyf0522332020-07-18 06:09:46968 EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));
mkwstb1d1a952016-06-22 14:58:05969
John Abd-El-Malek2d2173732018-04-25 13:40:51970 auto requests = data();
971 EXPECT_EQ(2u, requests.size());
mkwstb1d1a952016-06-22 14:58:05972
arthursonzogni224aa612017-12-07 15:31:51973 // User-initiated top-level navigations have a first-party that matches the
974 // URL to which they navigate, even if they fail to load. The navigation was
975 // initiated outside of a document, so there is no initiator.
John Abd-El-Malek2d2173732018-04-25 13:40:51976 EXPECT_EQ(top_url, requests[0].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10977 EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
978 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:51979 EXPECT_FALSE(requests[0].initiator.has_value());
mkwstb1d1a952016-06-22 14:58:05980
981 // Auxiliary navigations have a first-party that matches the URL to which they
982 // navigate, and an initiator that matches the document that triggered them.
John Abd-El-Malek2d2173732018-04-25 13:40:51983 EXPECT_EQ(auxiliary_url, requests[1].url);
Maks Orlovich5d02d9e02019-12-15 22:14:10984 EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
985 net::SiteForCookies::FromUrl(auxiliary_url)));
John Abd-El-Malek2d2173732018-04-25 13:40:51986 EXPECT_EQ(top_origin, requests[1].initiator);
mkwstb1d1a952016-06-22 14:58:05987}
988
John Abd-El-Malek2d2173732018-04-25 13:40:51989IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, FailedNavigation) {
mkwstb1d1a952016-06-22 14:58:05990 // Navigating to this URL will fail, as we haven't taught the host resolver
991 // about 'a.com'.
992 GURL top_url(embedded_test_server()->GetURL("a.com", "/simple_page.html"));
Daniel Cheng88186bd52017-10-20 08:14:46993 url::Origin top_origin = url::Origin::Create(top_url);
mkwstb1d1a952016-06-22 14:58:05994
995 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
996
John Abd-El-Malek2d2173732018-04-25 13:40:51997 auto requests = data();
998 EXPECT_EQ(1u, requests.size());
mkwstb1d1a952016-06-22 14:58:05999
arthursonzogni224aa612017-12-07 15:31:511000 // User-initiated top-level navigations have a first-party that matches the
1001 // URL to which they navigate, even if they fail to load. The navigation was
1002 // initiated outside of a document, so there is no initiator.
John Abd-El-Malek2d2173732018-04-25 13:40:511003 EXPECT_EQ(top_url, requests[0].url);
Maks Orlovich5d02d9e02019-12-15 22:14:101004 EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
1005 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:511006 EXPECT_FALSE(requests[0].initiator.has_value());
mkwstb1d1a952016-06-22 14:58:051007}
1008
John Abd-El-Malek2d2173732018-04-25 13:40:511009IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, CrossOriginNested) {
mkwstb1d1a952016-06-22 14:58:051010 GURL top_url(embedded_test_server()->GetURL(
1011 "a.com", "/cross_site_iframe_factory.html?a(b)"));
1012 GURL top_js_url(
1013 embedded_test_server()->GetURL("a.com", "/tree_parser_util.js"));
1014 GURL nested_url(embedded_test_server()->GetURL(
1015 "b.com", "/cross_site_iframe_factory.html?b()"));
1016 GURL nested_js_url(
1017 embedded_test_server()->GetURL("b.com", "/tree_parser_util.js"));
Daniel Cheng88186bd52017-10-20 08:14:461018 url::Origin top_origin = url::Origin::Create(top_url);
1019 url::Origin nested_origin = url::Origin::Create(nested_url);
mkwstb1d1a952016-06-22 14:58:051020
1021 NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
Tsuyoshi Horo18ae3602023-05-23 03:26:091022 WaitForRequests(4u);
mkwstb1d1a952016-06-22 14:58:051023
John Abd-El-Malek2d2173732018-04-25 13:40:511024 auto requests = data();
1025 EXPECT_EQ(4u, requests.size());
mkwstb1d1a952016-06-22 14:58:051026
arthursonzogni224aa612017-12-07 15:31:511027 // User-initiated top-level navigations have a |first-party|. The navigation
1028 // was initiated outside of a document, so there are no initiator.
John Abd-El-Malek2d2173732018-04-25 13:40:511029 EXPECT_EQ(top_url, requests[0].url);
Maks Orlovich5d02d9e02019-12-15 22:14:101030 EXPECT_TRUE(requests[0].site_for_cookies.IsEquivalent(
1031 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:511032 EXPECT_FALSE(requests[0].initiator.has_value());
mkwstb1d1a952016-06-22 14:58:051033
John Abd-El-Malek2d2173732018-04-25 13:40:511034 EXPECT_EQ(top_js_url, requests[1].url);
Maks Orlovich5d02d9e02019-12-15 22:14:101035 EXPECT_TRUE(requests[1].site_for_cookies.IsEquivalent(
1036 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:511037 EXPECT_EQ(top_origin, requests[1].initiator);
mkwstb1d1a952016-06-22 14:58:051038
mkwst4f2cb7d2016-06-23 06:32:251039 // Cross-origin frames have a first-party and initiator that matches the URL
Maks Orlovich5d02d9e02019-12-15 22:14:101040 // in which they're embedded (if they are the first cross-origin thing)
John Abd-El-Malek2d2173732018-04-25 13:40:511041 EXPECT_EQ(nested_url, requests[2].url);
Maks Orlovich5d02d9e02019-12-15 22:14:101042 EXPECT_TRUE(requests[2].site_for_cookies.IsEquivalent(
1043 net::SiteForCookies::FromOrigin(top_origin)));
John Abd-El-Malek2d2173732018-04-25 13:40:511044 EXPECT_EQ(top_origin, requests[2].initiator);
mkwstb1d1a952016-06-22 14:58:051045
1046 // Cross-origin subresource requests have a unique first-party, and an
1047 // initiator that matches the document in which they're embedded.
John Abd-El-Malek2d2173732018-04-25 13:40:511048 EXPECT_EQ(nested_js_url, requests[3].url);
Maks Orlovich5d02d9e02019-12-15 22:14:101049 EXPECT_TRUE(requests[3].site_for_cookies.IsNull());
John Abd-El-Malek2d2173732018-04-25 13:40:511050 EXPECT_EQ(nested_origin, requests[3].initiator);
mkwstb1d1a952016-06-22 14:58:051051}
1052
arthursonzogni224aa612017-12-07 15:31:511053// Regression test for https://crbug.com/648608. An attacker could trivially
1054// bypass cookies SameSite=Strict protections by navigating a new window twice.
John Abd-El-Malek6883212992018-04-25 22:32:221055IN_PROC_BROWSER_TEST_F(LoaderBrowserTest,
arthursonzogni224aa612017-12-07 15:31:511056 CookieSameSiteStrictOpenNewNamedWindowTwice) {
1057 ASSERT_TRUE(embedded_test_server()->Start());
1058
1059 // 1) Add cookies for 'a.com', one of them with the "SameSite=Strict" option.
1060 BrowserContext* context = shell()->web_contents()->GetBrowserContext();
1061 GURL a_url("http://a.com");
1062 EXPECT_TRUE(SetCookie(context, a_url, "cookie_A=A; SameSite=Strict;"));
1063 EXPECT_TRUE(SetCookie(context, a_url, "cookie_B=B"));
1064
1065 // 2) Navigate to malicious.com.
1066 EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL(
1067 "malicious.com", "/title1.html")));
1068
1069 // 2.1) malicious.com opens a new window to 'http://a.com/echoall'.
1070 GURL echoall_url = embedded_test_server()->GetURL("a.com", "/echoall");
1071 std::string script = base::StringPrintf("window.open('%s', 'named_frame');",
1072 echoall_url.spec().c_str());
1073 {
1074 TestNavigationObserver new_tab_observer(shell()->web_contents(), 1);
1075 new_tab_observer.StartWatchingNewWebContents();
Avi Drissmanc91bd8e2021-04-19 23:58:441076 EXPECT_TRUE(ExecJs(shell(), script));
arthursonzogni224aa612017-12-07 15:31:511077 new_tab_observer.Wait();
1078 ASSERT_EQ(2u, Shell::windows().size());
1079 Shell* new_shell = Shell::windows()[1];
1080 EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));
1081
1082 // Only the cookie without "SameSite=Strict" should be sent.
Avi Drissmanc91bd8e2021-04-19 23:58:441083 std::string html_content =
1084 EvalJs(new_shell, "document.body.textContent").ExtractString();
arthursonzogni224aa612017-12-07 15:31:511085 EXPECT_THAT(html_content.c_str(), Not(HasSubstr("cookie_A=A")));
1086 EXPECT_THAT(html_content.c_str(), HasSubstr("cookie_B=B"));
1087 }
1088
1089 // 2.2) Same as in 2.1). The difference is that the new tab will be reused.
1090 {
1091 Shell* new_shell = Shell::windows()[1];
1092 TestNavigationObserver new_tab_observer(new_shell->web_contents(), 1);
Avi Drissmanc91bd8e2021-04-19 23:58:441093 EXPECT_TRUE(ExecJs(shell(), script));
arthursonzogni224aa612017-12-07 15:31:511094 new_tab_observer.Wait();
1095 ASSERT_EQ(2u, Shell::windows().size());
1096 EXPECT_TRUE(WaitForLoadStop(new_shell->web_contents()));
1097
1098 // Only the cookie without "SameSite=Strict" should be sent.
Avi Drissmanc91bd8e2021-04-19 23:58:441099 std::string html_content =
1100 EvalJs(new_shell, "document.body.textContent").ExtractString();
arthursonzogni224aa612017-12-07 15:31:511101 EXPECT_THAT(html_content.c_str(), Not(HasSubstr("cookie_A=A")));
1102 EXPECT_THAT(html_content.c_str(), HasSubstr("cookie_B=B"));
1103 }
1104}
1105
Minggang Wangf6840ecf2019-07-29 05:15:021106class URLModifyingThrottle : public blink::URLLoaderThrottle {
John Abd-El-Malekc32804f2018-11-07 19:10:371107 public:
John Abd-El-Malekc16f6732018-11-22 05:06:491108 URLModifyingThrottle(bool modify_start, bool modify_redirect)
1109 : modify_start_(modify_start), modify_redirect_(modify_redirect) {}
Peter Boström828b9022021-09-21 02:28:431110
1111 URLModifyingThrottle(const URLModifyingThrottle&) = delete;
1112 URLModifyingThrottle& operator=(const URLModifyingThrottle&) = delete;
1113
John Abd-El-Malekc32804f2018-11-07 19:10:371114 ~URLModifyingThrottle() override = default;
1115
1116 void WillStartRequest(network::ResourceRequest* request,
1117 bool* defer) override {
Solomon Kinardab293bae2024-09-19 17:13:511118 if (!modify_start_) {
John Abd-El-Malekc16f6732018-11-22 05:06:491119 return;
Solomon Kinardab293bae2024-09-19 17:13:511120 }
John Abd-El-Malekc16f6732018-11-22 05:06:491121
John Abd-El-Malekc32804f2018-11-07 19:10:371122 GURL::Replacements replacements;
1123 replacements.SetQueryStr("foo=bar");
1124 request->url = request->url.ReplaceComponents(replacements);
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:581125 request->headers.SetHeader("Foo", "BarRequest");
1126 request->cors_exempt_headers.SetHeader("ExemptFoo", "ExemptBarRequest");
John Abd-El-Malekc32804f2018-11-07 19:10:371127 }
1128
John Abd-El-Malekc16f6732018-11-22 05:06:491129 void WillRedirectRequest(
1130 net::RedirectInfo* redirect_info,
Lucas Furukawa Gadani011886592019-10-23 17:12:241131 const network::mojom::URLResponseHead& response_head,
John Abd-El-Malekc16f6732018-11-22 05:06:491132 bool* defer,
1133 std::vector<std::string>* to_be_removed_request_headers,
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:581134 net::HttpRequestHeaders* modified_request_headers,
1135 net::HttpRequestHeaders* modified_cors_exempt_request_headers) override {
Solomon Kinardab293bae2024-09-19 17:13:511136 if (!modify_redirect_) {
John Abd-El-Malekc16f6732018-11-22 05:06:491137 return;
Solomon Kinardab293bae2024-09-19 17:13:511138 }
John Abd-El-Malekc16f6732018-11-22 05:06:491139
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:581140 modified_request_headers->SetHeader("Foo", "BarRedirect");
1141 modified_cors_exempt_request_headers->SetHeader("ExemptFoo",
1142 "ExemptBarRedirect");
John Abd-El-Malekc16f6732018-11-22 05:06:491143
Solomon Kinardab293bae2024-09-19 17:13:511144 if (modified_redirect_url_) {
John Abd-El-Malekc16f6732018-11-22 05:06:491145 return; // Only need to do this once.
Solomon Kinardab293bae2024-09-19 17:13:511146 }
John Abd-El-Malekc16f6732018-11-22 05:06:491147
1148 modified_redirect_url_ = true;
1149 GURL::Replacements replacements;
1150 replacements.SetQueryStr("foo=bar");
1151 redirect_info->new_url =
1152 redirect_info->new_url.ReplaceComponents(replacements);
1153 }
1154
John Abd-El-Malekc32804f2018-11-07 19:10:371155 private:
John Abd-El-Malekc16f6732018-11-22 05:06:491156 bool modify_start_;
1157 bool modify_redirect_;
1158 bool modified_redirect_url_ = false;
John Abd-El-Malekc32804f2018-11-07 19:10:371159};
1160
Scott Violet99861992023-02-08 01:20:121161class ThrottleContentBrowserClient
1162 : public ContentBrowserTestContentBrowserClient {
John Abd-El-Malekc32804f2018-11-07 19:10:371163 public:
John Abd-El-Malekc16f6732018-11-22 05:06:491164 ThrottleContentBrowserClient(bool modify_start, bool modify_redirect)
Scott Violet99861992023-02-08 01:20:121165 : modify_start_(modify_start), modify_redirect_(modify_redirect) {}
Peter Boström828b9022021-09-21 02:28:431166
1167 ThrottleContentBrowserClient(const ThrottleContentBrowserClient&) = delete;
1168 ThrottleContentBrowserClient& operator=(const ThrottleContentBrowserClient&) =
1169 delete;
1170
John Abd-El-Malekc32804f2018-11-07 19:10:371171 ~ThrottleContentBrowserClient() override {}
1172
1173 // ContentBrowserClient overrides:
Minggang Wangf6840ecf2019-07-29 05:15:021174 std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
Clark DuVall88b09d72019-08-05 18:58:131175 CreateURLLoaderThrottles(
John Abd-El-Malekc32804f2018-11-07 19:10:371176 const network::ResourceRequest& request,
Clark DuVall88b09d72019-08-05 18:58:131177 BrowserContext* browser_context,
John Abd-El-Malekc32804f2018-11-07 19:10:371178 const base::RepeatingCallback<WebContents*()>& wc_getter,
1179 NavigationUIData* navigation_ui_data,
Avi Drissman580a3da62024-09-04 16:16:561180 FrameTreeNodeId frame_tree_node_id,
Vikram Pasupathyb53137e52024-02-01 01:46:531181 std::optional<int64_t> navigation_id) override {
Minggang Wangf6840ecf2019-07-29 05:15:021182 std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
John Abd-El-Malekc16f6732018-11-22 05:06:491183 auto throttle =
1184 std::make_unique<URLModifyingThrottle>(modify_start_, modify_redirect_);
John Abd-El-Malekc32804f2018-11-07 19:10:371185 throttles.push_back(std::move(throttle));
1186 return throttles;
1187 }
1188
1189 private:
John Abd-El-Malekc16f6732018-11-22 05:06:491190 bool modify_start_;
1191 bool modify_redirect_;
John Abd-El-Malekc32804f2018-11-07 19:10:371192};
1193
Minggang Wangf6840ecf2019-07-29 05:15:021194// Ensures if a URLLoaderThrottle modifies a URL in WillStartRequest the
1195// new request matches
John Abd-El-Malekc16f6732018-11-22 05:06:491196IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, URLLoaderThrottleStartModify) {
John Abd-El-Malekc32804f2018-11-07 19:10:371197 base::Lock lock;
John Abd-El-Malekc16f6732018-11-22 05:06:491198 ThrottleContentBrowserClient content_browser_client(true, false);
John Abd-El-Malekc32804f2018-11-07 19:10:371199
1200 std::set<GURL> urls_requested;
John Abd-El-Malekc460cb62018-11-08 00:29:561201 std::map<GURL, net::test_server::HttpRequest::HeaderMap> header_map;
John Abd-El-Malekc32804f2018-11-07 19:10:371202 embedded_test_server()->RegisterRequestMonitor(base::BindLambdaForTesting(
1203 [&](const net::test_server::HttpRequest& request) {
1204 base::AutoLock auto_lock(lock);
1205 urls_requested.insert(request.GetURL());
John Abd-El-Malekc460cb62018-11-08 00:29:561206 header_map[request.GetURL()] = request.headers;
John Abd-El-Malekc32804f2018-11-07 19:10:371207 }));
1208
1209 ASSERT_TRUE(embedded_test_server()->Start());
1210
1211 GURL url = embedded_test_server()->GetURL("/simple_page.html");
Alex Moshchuk765684f52019-09-21 01:16:411212 GURL expected_url(url.spec() + "?foo=bar");
1213 EXPECT_TRUE(
1214 NavigateToURL(shell(), url, expected_url /* expected_commit_url */));
John Abd-El-Malekc32804f2018-11-07 19:10:371215
1216 {
John Abd-El-Malekc32804f2018-11-07 19:10:371217 base::AutoLock auto_lock(lock);
1218 ASSERT_TRUE(urls_requested.find(expected_url) != urls_requested.end());
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:581219 ASSERT_TRUE(header_map[expected_url]["Foo"] == "BarRequest");
1220 ASSERT_TRUE(header_map[expected_url]["ExemptFoo"] == "ExemptBarRequest");
John Abd-El-Malekc32804f2018-11-07 19:10:371221 }
John Abd-El-Malekc32804f2018-11-07 19:10:371222}
1223
John Abd-El-Malekc16f6732018-11-22 05:06:491224// Ensures if a URLLoaderThrottle modifies a URL and headers in
1225// WillRedirectRequest the new request matches.
1226IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, URLLoaderThrottleRedirectModify) {
1227 base::Lock lock;
1228 ThrottleContentBrowserClient content_browser_client(false, true);
John Abd-El-Malekc16f6732018-11-22 05:06:491229
1230 std::set<GURL> urls_requested;
1231 std::map<GURL, net::test_server::HttpRequest::HeaderMap> header_map;
1232 embedded_test_server()->RegisterRequestMonitor(base::BindLambdaForTesting(
1233 [&](const net::test_server::HttpRequest& request) {
1234 base::AutoLock auto_lock(lock);
1235 urls_requested.insert(request.GetURL());
1236 header_map[request.GetURL()] = request.headers;
1237 }));
1238
1239 ASSERT_TRUE(embedded_test_server()->Start());
1240
1241 GURL url =
1242 embedded_test_server()->GetURL("/server-redirect?simple_page.html");
Alex Moshchuk765684f52019-09-21 01:16:411243 GURL expected_url =
1244 embedded_test_server()->GetURL("/simple_page.html?foo=bar");
1245 EXPECT_TRUE(
1246 NavigateToURL(shell(), url, expected_url /* expected_commit_url */));
John Abd-El-Malekc16f6732018-11-22 05:06:491247
1248 {
1249 base::AutoLock auto_lock(lock);
Takashi Toyoshimaeb2ba20c52020-04-27 16:34:581250 ASSERT_EQ(header_map[expected_url]["Foo"], "BarRedirect");
1251 ASSERT_EQ(header_map[expected_url]["ExemptFoo"], "ExemptBarRedirect");
John Abd-El-Malekc16f6732018-11-22 05:06:491252 ASSERT_NE(urls_requested.find(expected_url), urls_requested.end());
1253 }
John Abd-El-Malekc16f6732018-11-22 05:06:491254}
1255
Tsuyoshi Horo1684bc02024-06-24 06:11:351256class LoaderNoScriptStreamingBrowserTest : public ContentBrowserTest {
1257 public:
1258 LoaderNoScriptStreamingBrowserTest() = default;
1259 LoaderNoScriptStreamingBrowserTest(
1260 const LoaderNoScriptStreamingBrowserTest&) = delete;
1261 LoaderNoScriptStreamingBrowserTest& operator=(
1262 const LoaderNoScriptStreamingBrowserTest&) = delete;
1263 ~LoaderNoScriptStreamingBrowserTest() override = default;
1264
1265 void SetUpCommandLine(base::CommandLine* command_line) override {
1266 command_line->AppendSwitchASCII("js-flags", "--no-script-streaming");
1267 }
1268};
1269
1270// Regression test for https://crbug.com/348520461
1271// Loading a script should not cause a crash even when Script Streaming
1272// is disabled on V8 side.
1273IN_PROC_BROWSER_TEST_F(LoaderNoScriptStreamingBrowserTest, LoadScript) {
1274 ASSERT_TRUE(embedded_test_server()->Start());
1275 EXPECT_TRUE(NavigateToURL(
1276 shell(), embedded_test_server()->GetURL("/loader/blank.html")));
1277 std::string expected_title("DONE");
1278 std::u16string expected_title16(ASCIIToUTF16(expected_title));
1279 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
1280 ASSERT_TRUE(ExecJs(shell(), R"(
1281 (() => {
1282 const script = document.createElement('script');
1283 script.src = './change_title.js';
1284 document.body.appendChild(script);
1285 })();
1286 )"));
1287 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
1288}
1289
Tsuyoshi Horoffd487362024-08-29 21:11:171290// Regression test for https://crbug.com/362788339
1291// Tests that script can be loaded when the server responded 304 response.
Alan Screenb832de02024-09-25 02:05:461292// TODO(crbug.com/369439037): Re-enable once flakiness is resolved for Windows
1293// ASAN.
1294#if BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER)
1295#define MAYBE_Subresource304Response DISABLED_Subresource304Response
1296#else
1297#define MAYBE_Subresource304Response Subresource304Response
1298#endif
1299IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, MAYBE_Subresource304Response) {
Tsuyoshi Horoffd487362024-08-29 21:11:171300 embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
1301 [](const net::test_server::HttpRequest& request)
1302 -> std::unique_ptr<net::test_server::HttpResponse> {
1303 if (request.relative_url == "/test.html") {
1304 auto response =
1305 std::make_unique<net::test_server::BasicHttpResponse>();
1306 response->set_content_type("text/html");
1307 const size_t kScriptCount = 100;
1308 std::vector<std::string> html_strings;
1309 html_strings.emplace_back("<head><title></title><head><script>");
1310 html_strings.emplace_back("const kScriptCount = ");
1311 html_strings.emplace_back(base::NumberToString(kScriptCount));
1312 html_strings.emplace_back(";\n");
1313 html_strings.emplace_back(R"(
1314 let count = 0;
1315 function done() {
1316 if (++count == kScriptCount) {
1317 document.title='Scripts Loaded';
1318 }
1319 }
1320 )");
1321 html_strings.emplace_back("</script>");
1322 for (size_t i = 0; i < kScriptCount; ++i) {
1323 html_strings.emplace_back("<script src=\"./test.js?");
1324 html_strings.emplace_back(base::NumberToString(i));
1325 html_strings.emplace_back("\"></script>");
1326 }
1327 response->set_content(base::StrCat(html_strings));
1328 return response;
1329 } else if (request.relative_url.starts_with("/test.js?")) {
1330 auto response =
1331 std::make_unique<net::test_server::BasicHttpResponse>();
1332 if (request.headers.contains("if-modified-since")) {
1333 response->set_code(net::HTTP_NOT_MODIFIED);
1334 return response;
1335 }
1336 response->set_content_type("application/javascript");
1337 response->set_content("done();");
1338 response->AddCustomHeader("Cache-Control", "max-age=0, no-cache");
1339 response->AddCustomHeader("pragma", "no-cache");
1340 response->AddCustomHeader("Last-Modified",
1341 "Wed, 20 Dec 2023 01:00:00 GMT");
1342 return response;
1343 }
1344 return nullptr;
1345 }));
1346 ASSERT_TRUE(embedded_test_server()->Start());
1347 {
1348 std::u16string expected_title(u"Scripts Loaded");
1349 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
1350 EXPECT_TRUE(
1351 NavigateToURL(shell(), embedded_test_server()->GetURL("/test.html")));
1352 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
1353 }
1354 {
1355 {
1356 std::u16string expected_title(u"Title Cleared");
1357 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
1358 EXPECT_EQ("Title Cleared",
1359 EvalJs(shell(), "document.title = 'Title Cleared';"));
1360 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
1361 }
1362 {
1363 std::u16string expected_title(u"Scripts Loaded");
1364 TitleWatcher title_watcher(shell()->web_contents(), expected_title);
1365 shell()->Reload();
1366 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
1367 }
1368 }
1369}
1370
[email protected]854e1312012-07-30 17:26:301371} // namespace content