[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_worker_browsertest.cc
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This file tests that Web Workers (a Content feature) work in the Chromium
6 // embedder.
7
8 #include "base/containers/contains.h"
9 #include "base/feature_list.h"
10 #include "base/functional/bind.h"
11 #include "base/functional/callback.h"
12 #include "base/run_loop.h"
13 #include "base/strings/strcat.h"
14 #include "base/test/bind.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "components/content_settings/core/browser/cookie_settings.h"
20 #include "components/content_settings/core/common/pref_names.h"
21 #include "components/prefs/pref_service.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/test/browser_test.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "content/public/test/url_loader_interceptor.h"
26 #include "net/test/embedded_test_server/embedded_test_server.h"
27 #include "net/test/embedded_test_server/http_request.h"
28 #include "net/test/embedded_test_server/http_response.h"
29 #include "third_party/blink/public/common/features.h"
30 #include "third_party/re2/src/re2/re2.h"
31
32 // A simple fixture used for testing dedicated workers and shared workers. The
33 // fixture stashes the HTTP request to the worker script for inspecting the
34 // headers.
35 //
36 // This is in //chrome instead of //content since the tests exercise the
37 // |kBlockThirdPartyCookies| preference which is not a //content concept.
38 class ChromeWorkerBrowserTest : public InProcessBrowserTest {
39  public:
40   void SetUp() override {
41     embedded_test_server()->RegisterRequestHandler(
42         base::BindRepeating(&ChromeWorkerBrowserTest::CaptureHeaderHandler,
43                             base::Unretained(this), "/capture"));
44     ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
45     InProcessBrowserTest::SetUp();
46   }
47
48   void SetUpOnMainThread() override {
49     embedded_test_server()->StartAcceptingConnections();
50   }
51
52  protected:
53   // Tests worker script fetch (always same-origin) is not affected by the
54   // third-party cookie blocking configuration.
55   // This is the regression test for https://crbug.com/933287.
56   void TestWorkerScriptFetchWithThirdPartyCookieBlocking(
57       content_settings::CookieControlsMode cookie_controls_mode,
58       const std::string& test_url) {
59     const std::string kCookie = "foo=bar";
60
61     // Set up third-party cookie blocking.
62     browser()->profile()->GetPrefs()->SetInteger(
63         prefs::kCookieControlsMode, static_cast<int>(cookie_controls_mode));
64
65     // Make sure cookies are not set.
66     ASSERT_TRUE(
67         GetCookies(browser()->profile(), embedded_test_server()->base_url())
68             .empty());
69
70     // Request for the worker script should not send cookies.
71     {
72       base::RunLoop run_loop;
73       quit_closure_ = run_loop.QuitClosure();
74       ASSERT_TRUE(ui_test_utils::NavigateToURL(
75           browser(), embedded_test_server()->GetURL(test_url)));
76       run_loop.Run();
77       EXPECT_FALSE(base::Contains(header_map_, "Cookie"));
78     }
79
80     // Set a cookie.
81     ASSERT_TRUE(SetCookie(browser()->profile(),
82                           embedded_test_server()->base_url(), kCookie));
83
84     // Request for the worker script should send the cookie regardless of the
85     // third-party cookie blocking configuration.
86     {
87       base::RunLoop run_loop;
88       quit_closure_ = run_loop.QuitClosure();
89       ASSERT_TRUE(ui_test_utils::NavigateToURL(
90           browser(), embedded_test_server()->GetURL(test_url)));
91       run_loop.Run();
92       EXPECT_TRUE(base::Contains(header_map_, "Cookie"));
93       EXPECT_EQ(kCookie, header_map_["Cookie"]);
94     }
95   }
96
97   // TODO(nhiroki): Add tests for creating workers from third-party iframes
98   // while third-party cookie blocking is enabled. This expects that cookies are
99   // not blocked.
100
101  private:
102   std::unique_ptr<net::test_server::HttpResponse> CaptureHeaderHandler(
103       const std::string& path,
104       const net::test_server::HttpRequest& request) {
105     if (request.GetURL().path() != path)
106       return nullptr;
107     // Stash the HTTP request headers.
108     header_map_ = request.headers;
109     std::move(quit_closure_).Run();
110     return std::make_unique<net::test_server::BasicHttpResponse>();
111   }
112
113   net::test_server::HttpRequest::HeaderMap header_map_;
114   base::OnceClosure quit_closure_;
115 };
116
117 IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest,
118                        DedicatedWorkerScriptFetchWithThirdPartyBlocking) {
119   TestWorkerScriptFetchWithThirdPartyCookieBlocking(
120       content_settings::CookieControlsMode::kBlockThirdParty,
121       "/workers/create_dedicated_worker.html?worker_url=/capture");
122 }
123
124 IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest,
125                        DedicatedWorkerScriptFetchWithoutThirdPartyBlocking) {
126   TestWorkerScriptFetchWithThirdPartyCookieBlocking(
127       content_settings::CookieControlsMode::kOff,
128       "/workers/create_dedicated_worker.html?worker_url=/capture");
129 }
130
131 IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest,
132                        SharedWorkerScriptFetchWithThirdPartyBlocking) {
133   TestWorkerScriptFetchWithThirdPartyCookieBlocking(
134       content_settings::CookieControlsMode::kBlockThirdParty,
135       "/workers/create_shared_worker.html?worker_url=/capture");
136 }
137
138 IN_PROC_BROWSER_TEST_F(ChromeWorkerBrowserTest,
139                        SharedWorkerScriptFetchWithoutThirdPartyBlocking) {
140   TestWorkerScriptFetchWithThirdPartyCookieBlocking(
141       content_settings::CookieControlsMode::kOff,
142       "/workers/create_shared_worker.html?worker_url=/capture");
143 }
144
145 // A test fixture used for testing that dedicated and shared workers have the
146 // correct user agent value, it should always be the reduced user agent string.
147 class ChromeWorkerUserAgentBrowserTest : public InProcessBrowserTest {
148  public:
149   ChromeWorkerUserAgentBrowserTest() = default;
150
151   // The URL that was used to test user-agent.
152   static constexpr char kOriginUrl[] = "https://127.0.0.1:44444";
153
154   // We use a URLLoaderInterceptor, rather than the EmbeddedTestServer, since
155   // EmbeddedTestServer serves content on a random port.
156   std::unique_ptr<content::URLLoaderInterceptor> CreateUrlLoaderInterceptor() {
157     return std::make_unique<content::URLLoaderInterceptor>(
158         base::BindLambdaForTesting(
159             [&](content::URLLoaderInterceptor::RequestParams* params) {
160               if (expected_request_urls_.find(params->url_request.url) ==
161                   expected_request_urls_.end())
162                 return false;
163
164               std::string path = "chrome/test/data/workers";
165               path.append(std::string(params->url_request.url.path_piece()));
166
167               std::string headers = "HTTP/1.1 200 OK\n";
168               base::StrAppend(
169                   &headers,
170                   {"Content-Type: text/",
171                    base::EndsWith(params->url_request.url.path_piece(), ".js")
172                        ? "javascript"
173                        : "html",
174                    "\n"});
175               content::URLLoaderInterceptor::WriteResponse(
176                   path, params->client.get(), &headers);
177
178               return true;
179             }));
180   }
181
182   void SetExpectedRequestURLs(const std::set<GURL>& expected_request_urls) {
183     expected_request_urls_ = expected_request_urls;
184   }
185
186   // Check whether the user agent minor version matches "0.0.0" and we expect
187   // the user agent always to be reduced.
188   void CheckUserAgentString(const std::string& user_agent_value) {
189     // A regular expression that matches Chrome/{major_version}.{minor_version}
190     // in the User-Agent string, where the {minor_version} is captured.
191     static constexpr char kChromeVersionRegex[] =
192         "Chrome/[0-9]+\\.([0-9]+\\.[0-9]+\\.[0-9]+)";
193     // The minor version in the reduced UA string is always "0.0.0".
194     static constexpr char kReducedMinorVersion[] = "0.0.0";
195
196     std::string minor_version;
197     EXPECT_TRUE(re2::RE2::PartialMatch(user_agent_value, kChromeVersionRegex,
198                                        &minor_version));
199
200     EXPECT_EQ(minor_version, kReducedMinorVersion);
201   }
202
203  private:
204   std::set<GURL> expected_request_urls_;
205 };
206
207 constexpr char ChromeWorkerUserAgentBrowserTest::kOriginUrl[];
208
209 IN_PROC_BROWSER_TEST_F(ChromeWorkerUserAgentBrowserTest, SharedWorker) {
210   const GURL main_page_url = GURL(base::StrCat(
211       {kOriginUrl,
212        "/create_shared_worker.html?worker_url=onconnect_user_agent.js"}));
213   const GURL worker_url =
214       GURL(base::StrCat({kOriginUrl, "/onconnect_user_agent.js"}));
215   SetExpectedRequestURLs({main_page_url, worker_url});
216
217   std::unique_ptr<content::URLLoaderInterceptor> interceptor =
218       CreateUrlLoaderInterceptor();
219
220   // Navigate to the page that has the scripts for registering the worker.
221   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_page_url));
222
223   // Check the result of navigator.userAgent called from the worker.
224   CheckUserAgentString(
225       EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
226              "waitForMessage()")
227           .ExtractString());
228 }
229
230 IN_PROC_BROWSER_TEST_F(ChromeWorkerUserAgentBrowserTest,
231                        DedicatedWorkerCreatedFromFrame) {
232   const GURL main_page_url = GURL(base::StrCat(
233       {kOriginUrl, "/create_dedicated_worker.html?worker_url=user_agent.js"}));
234   const GURL worker_url = GURL(base::StrCat({kOriginUrl, "/user_agent.js"}));
235   SetExpectedRequestURLs({main_page_url, worker_url});
236
237   std::unique_ptr<content::URLLoaderInterceptor> interceptor =
238       CreateUrlLoaderInterceptor();
239
240   // Navigate to the page that has the scripts for registering the worker.
241   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_page_url));
242
243   // Check the result of navigator.userAgent called from the worker.
244   CheckUserAgentString(
245       EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
246              "waitForMessage()")
247           .ExtractString());
248 }
249
250 IN_PROC_BROWSER_TEST_F(ChromeWorkerUserAgentBrowserTest,
251                        DedicatedWorkerCreatedFromDedicatedWorker) {
252   const GURL main_page_url =
253       GURL(base::StrCat({kOriginUrl,
254                          "/create_dedicated_worker.html?worker_url=parent_"
255                          "worker_user_agent.js"}));
256   const GURL worker_url =
257       GURL(base::StrCat({kOriginUrl, "/parent_worker_user_agent.js"}));
258   const GURL user_agent_url =
259       GURL(base::StrCat({kOriginUrl, "/user_agent.js"}));
260   SetExpectedRequestURLs({main_page_url, worker_url, user_agent_url});
261
262   std::unique_ptr<content::URLLoaderInterceptor> interceptor =
263       CreateUrlLoaderInterceptor();
264
265   // Navigate to the page that has the scripts for registering the worker.
266   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_page_url));
267
268   // Check the result of navigator.userAgent called from the worker.
269   CheckUserAgentString(
270       EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
271              "waitForMessage()")
272           .ExtractString());
273 }