blob: f613429258406951b015b798dc168b4126df60c0 [file] [log] [blame]
yhirano01a5d662015-02-12 04:33:061// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
Victor Costan85874942018-02-28 04:11:446#include <utility>
yhirano01a5d662015-02-12 04:33:067
Sebastien Marchand6d0558fd2019-01-25 16:49:378#include "base/bind.h"
yhirano01a5d662015-02-12 04:33:069#include "base/callback_forward.h"
10#include "base/memory/weak_ptr.h"
yhirano01a5d662015-02-12 04:33:0611#include "base/run_loop.h"
12#include "base/strings/string_util.h"
13#include "base/strings/stringprintf.h"
gabf767595f2016-05-11 18:50:3514#include "base/threading/thread_task_runner_handle.h"
Victor Costan85874942018-02-28 04:11:4415#include "net/cookies/canonical_cookie.h"
16#include "net/cookies/canonical_cookie_test_helpers.h"
yhirano01a5d662015-02-12 04:33:0617#include "net/cookies/cookie_store.h"
Yutaka Hirano2f65eec2018-05-23 01:58:2218#include "net/http/http_request_headers.h"
yhirano01a5d662015-02-12 04:33:0619#include "net/socket/socket_test_util.h"
20#include "net/websockets/websocket_stream_create_test_base.h"
21#include "net/websockets/websocket_test_util.h"
Victor Costan85874942018-02-28 04:11:4422#include "testing/gmock/include/gmock/gmock.h"
yhirano01a5d662015-02-12 04:33:0623#include "testing/gtest/include/gtest/gtest.h"
24#include "url/gurl.h"
mkwst4997ce82015-07-25 12:00:0525#include "url/origin.h"
yhirano01a5d662015-02-12 04:33:0626
27namespace net {
28namespace {
29
30using ::testing::TestWithParam;
31using ::testing::ValuesIn;
32
33const char kNoCookieHeader[] = "";
34
35class TestBase : public WebSocketStreamCreateTestBase {
36 public:
37 void CreateAndConnect(const GURL& url,
mkwst4997ce82015-07-25 12:00:0538 const url::Origin& origin,
Mike Westb85da8ed2017-08-10 14:16:4639 const GURL& site_for_cookies,
yhirano01a5d662015-02-12 04:33:0640 const std::string& cookie_header,
41 const std::string& response_body) {
42 // We assume cookie_header ends with CRLF if not empty, as
43 // WebSocketStandardRequestWithCookies requires. Use AddCRLFIfNotEmpty
44 // in a call site.
brettwa7ff1b292015-07-16 17:49:2945 CHECK(cookie_header.empty() ||
46 base::EndsWith(cookie_header, "\r\n", base::CompareCase::SENSITIVE));
yhirano01a5d662015-02-12 04:33:0647
48 url_request_context_host_.SetExpectations(
49 WebSocketStandardRequestWithCookies(url.path(), url.host(), origin,
alladacef397d2016-06-29 17:52:2350 cookie_header, std::string(),
51 std::string()),
yhirano01a5d662015-02-12 04:33:0652 response_body);
Yutaka Hirano2f65eec2018-05-23 01:58:2253 CreateAndConnectStream(url, NoSubProtocols(), origin, site_for_cookies,
54 HttpRequestHeaders(), nullptr);
yhirano01a5d662015-02-12 04:33:0655 }
56
57 std::string AddCRLFIfNotEmpty(const std::string& s) {
58 return s.empty() ? s : s + "\r\n";
59 }
60};
61
62struct ClientUseCookieParameter {
63 // The URL for the WebSocket connection.
64 const char* const url;
65 // The URL for the previously set cookies.
66 const char* const cookie_url;
67 // The previously set cookies contents.
68 const char* const cookie_line;
69 // The Cookie: HTTP header expected to appear in the WS request. An empty
70 // string means there is no Cookie: header.
71 const char* const cookie_header;
72};
73
74class WebSocketStreamClientUseCookieTest
75 : public TestBase,
76 public TestWithParam<ClientUseCookieParameter> {
77 public:
78 ~WebSocketStreamClientUseCookieTest() override {
79 // Permit any endpoint locks to be released.
80 stream_request_.reset();
81 stream_.reset();
82 base::RunLoop().RunUntilIdle();
83 }
84
85 static void SetCookieHelperFunction(const base::Closure& task,
86 base::WeakPtr<bool> weak_is_called,
87 base::WeakPtr<bool> weak_result,
88 bool success) {
89 *weak_is_called = true;
90 *weak_result = success;
91 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
92 }
93};
94
95struct ServerSetCookieParameter {
96 // The URL for the WebSocket connection.
97 const char* const url;
98 // The URL used to query cookies after the response received.
99 const char* const cookie_url;
100 // The cookies expected to appear for |cookie_url| inquiry.
101 const char* const cookie_line;
102 // The Set-Cookie: HTTP header attached to the response.
103 const char* const cookie_header;
104};
105
106class WebSocketStreamServerSetCookieTest
107 : public TestBase,
108 public TestWithParam<ServerSetCookieParameter> {
109 public:
110 ~WebSocketStreamServerSetCookieTest() override {
111 // Permit any endpoint locks to be released.
112 stream_request_.reset();
113 stream_.reset();
114 base::RunLoop().RunUntilIdle();
115 }
116
Aaron Tagliaboschia4c64b52019-01-25 03:28:49117 static void GetCookieListHelperFunction(
118 base::OnceClosure task,
119 base::WeakPtr<bool> weak_is_called,
120 base::WeakPtr<CookieList> weak_result,
121 const CookieList& cookie_list,
122 const CookieStatusList& excluded_cookies) {
yhirano01a5d662015-02-12 04:33:06123 *weak_is_called = true;
Victor Costan85874942018-02-28 04:11:44124 *weak_result = cookie_list;
125 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task));
yhirano01a5d662015-02-12 04:33:06126 }
127};
128
129TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
130 // For wss tests.
Bence Béky63842f02018-03-05 13:48:21131 url_request_context_host_.AddSSLSocketDataProvider(
132 std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
yhirano01a5d662015-02-12 04:33:06133
134 CookieStore* store =
135 url_request_context_host_.GetURLRequestContext()->cookie_store();
136
137 const GURL url(GetParam().url);
138 const GURL cookie_url(GetParam().cookie_url);
Daniel Cheng88186bd52017-10-20 08:14:46139 const url::Origin origin =
140 url::Origin::Create(GURL("http://www.example.com"));
Mike Westb85da8ed2017-08-10 14:16:46141 const GURL site_for_cookies("http://www.example.com/");
yhirano01a5d662015-02-12 04:33:06142 const std::string cookie_line(GetParam().cookie_line);
143 const std::string cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header));
144
145 bool is_called = false;
146 bool set_cookie_result = false;
147 base::WeakPtrFactory<bool> weak_is_called(&is_called);
148 base::WeakPtrFactory<bool> weak_set_cookie_result(&set_cookie_result);
149
150 base::RunLoop run_loop;
151 store->SetCookieWithOptionsAsync(
152 cookie_url, cookie_line, CookieOptions(),
153 base::Bind(&SetCookieHelperFunction, run_loop.QuitClosure(),
154 weak_is_called.GetWeakPtr(),
155 weak_set_cookie_result.GetWeakPtr()));
156 run_loop.Run();
157 ASSERT_TRUE(is_called);
158 ASSERT_TRUE(set_cookie_result);
159
Mike Westb85da8ed2017-08-10 14:16:46160 CreateAndConnect(url, origin, site_for_cookies, cookie_header,
tyoshino8572d572016-07-13 06:29:48161 WebSocketStandardResponse(""));
yhirano01a5d662015-02-12 04:33:06162 WaitUntilConnectDone();
163 EXPECT_FALSE(has_failed());
164}
165
166TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) {
167 // For wss tests.
Bence Béky63842f02018-03-05 13:48:21168 url_request_context_host_.AddSSLSocketDataProvider(
169 std::make_unique<SSLSocketDataProvider>(ASYNC, OK));
yhirano01a5d662015-02-12 04:33:06170
171 const GURL url(GetParam().url);
172 const GURL cookie_url(GetParam().cookie_url);
Daniel Cheng88186bd52017-10-20 08:14:46173 const url::Origin origin =
174 url::Origin::Create(GURL("http://www.example.com"));
Mike Westb85da8ed2017-08-10 14:16:46175 const GURL site_for_cookies("http://www.example.com/");
yhirano01a5d662015-02-12 04:33:06176 const std::string cookie_line(GetParam().cookie_line);
177 const std::string cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header));
178
179 const std::string response = base::StringPrintf(
180 "HTTP/1.1 101 Switching Protocols\r\n"
181 "Upgrade: websocket\r\n"
182 "Connection: Upgrade\r\n"
183 "%s"
184 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
185 "\r\n",
186 cookie_header.c_str());
187
188 CookieStore* store =
189 url_request_context_host_.GetURLRequestContext()->cookie_store();
190
Mike Westb85da8ed2017-08-10 14:16:46191 CreateAndConnect(url, origin, site_for_cookies, "", response);
yhirano01a5d662015-02-12 04:33:06192 WaitUntilConnectDone();
193 EXPECT_FALSE(has_failed());
194
195 bool is_called = false;
Victor Costan85874942018-02-28 04:11:44196 CookieList get_cookie_list_result;
yhirano01a5d662015-02-12 04:33:06197 base::WeakPtrFactory<bool> weak_is_called(&is_called);
Victor Costan85874942018-02-28 04:11:44198 base::WeakPtrFactory<CookieList> weak_get_cookie_list_result(
199 &get_cookie_list_result);
yhirano01a5d662015-02-12 04:33:06200 base::RunLoop run_loop;
Victor Costan85874942018-02-28 04:11:44201 store->GetCookieListWithOptionsAsync(
yhirano01a5d662015-02-12 04:33:06202 cookie_url, CookieOptions(),
Victor Costan85874942018-02-28 04:11:44203 base::BindOnce(&GetCookieListHelperFunction, run_loop.QuitClosure(),
204 weak_is_called.GetWeakPtr(),
205 weak_get_cookie_list_result.GetWeakPtr()));
yhirano01a5d662015-02-12 04:33:06206 run_loop.Run();
207 EXPECT_TRUE(is_called);
Victor Costan85874942018-02-28 04:11:44208 EXPECT_THAT(get_cookie_list_result, MatchesCookieLine(cookie_line));
yhirano01a5d662015-02-12 04:33:06209}
210
211// Test parameters definitions follow...
212
213const ClientUseCookieParameter kClientUseCookieParameters[] = {
214 // Non-secure cookies for ws
215 {"ws://www.example.com",
216 "http://www.example.com",
217 "test-cookie",
218 "Cookie: test-cookie"},
219
220 {"ws://www.example.com",
221 "https://www.example.com",
222 "test-cookie",
223 "Cookie: test-cookie"},
224
225 {"ws://www.example.com",
226 "ws://www.example.com",
227 "test-cookie",
228 "Cookie: test-cookie"},
229
230 {"ws://www.example.com",
231 "wss://www.example.com",
232 "test-cookie",
233 "Cookie: test-cookie"},
234
235 // Non-secure cookies for wss
236 {"wss://www.example.com",
237 "http://www.example.com",
238 "test-cookie",
239 "Cookie: test-cookie"},
240
241 {"wss://www.example.com",
242 "https://www.example.com",
243 "test-cookie",
244 "Cookie: test-cookie"},
245
246 {"wss://www.example.com",
247 "ws://www.example.com",
248 "test-cookie",
249 "Cookie: test-cookie"},
250
251 {"wss://www.example.com",
252 "wss://www.example.com",
253 "test-cookie",
254 "Cookie: test-cookie"},
255
256 // Secure-cookies for ws
257 {"ws://www.example.com",
258 "https://www.example.com",
259 "test-cookie; secure",
260 kNoCookieHeader},
261
262 {"ws://www.example.com",
263 "wss://www.example.com",
264 "test-cookie; secure",
265 kNoCookieHeader},
266
267 // Secure-cookies for wss
268 {"wss://www.example.com",
269 "https://www.example.com",
270 "test-cookie; secure",
271 "Cookie: test-cookie"},
272
273 {"wss://www.example.com",
274 "wss://www.example.com",
275 "test-cookie; secure",
276 "Cookie: test-cookie"},
277
278 // Non-secure cookies for ws (sharing domain)
279 {"ws://www.example.com",
280 "http://www2.example.com",
281 "test-cookie; Domain=example.com",
282 "Cookie: test-cookie"},
283
284 {"ws://www.example.com",
285 "https://www2.example.com",
286 "test-cookie; Domain=example.com",
287 "Cookie: test-cookie"},
288
289 {"ws://www.example.com",
290 "ws://www2.example.com",
291 "test-cookie; Domain=example.com",
292 "Cookie: test-cookie"},
293
294 {"ws://www.example.com",
295 "wss://www2.example.com",
296 "test-cookie; Domain=example.com",
297 "Cookie: test-cookie"},
298
299 // Non-secure cookies for wss (sharing domain)
300 {"wss://www.example.com",
301 "http://www2.example.com",
302 "test-cookie; Domain=example.com",
303 "Cookie: test-cookie"},
304
305 {"wss://www.example.com",
306 "https://www2.example.com",
307 "test-cookie; Domain=example.com",
308 "Cookie: test-cookie"},
309
310 {"wss://www.example.com",
311 "ws://www2.example.com",
312 "test-cookie; Domain=example.com",
313 "Cookie: test-cookie"},
314
315 {"wss://www.example.com",
316 "wss://www2.example.com",
317 "test-cookie; Domain=example.com",
318 "Cookie: test-cookie"},
319
320 // Secure-cookies for ws (sharing domain)
321 {"ws://www.example.com",
322 "https://www2.example.com",
323 "test-cookie; Domain=example.com; secure",
324 kNoCookieHeader},
325
326 {"ws://www.example.com",
327 "wss://www2.example.com",
328 "test-cookie; Domain=example.com; secure",
329 kNoCookieHeader},
330
331 // Secure-cookies for wss (sharing domain)
332 {"wss://www.example.com",
333 "https://www2.example.com",
334 "test-cookie; Domain=example.com; secure",
335 "Cookie: test-cookie"},
336
337 {"wss://www.example.com",
338 "wss://www2.example.com",
339 "test-cookie; Domain=example.com; secure",
340 "Cookie: test-cookie"},
341
342 // Non-matching cookies for ws
343 {"ws://www.example.com",
344 "http://www2.example.com",
345 "test-cookie",
346 kNoCookieHeader},
347
348 {"ws://www.example.com",
349 "https://www2.example.com",
350 "test-cookie",
351 kNoCookieHeader},
352
353 {"ws://www.example.com",
354 "ws://www2.example.com",
355 "test-cookie",
356 kNoCookieHeader},
357
358 {"ws://www.example.com",
359 "wss://www2.example.com",
360 "test-cookie",
361 kNoCookieHeader},
362
363 // Non-matching cookies for wss
364 {"wss://www.example.com",
365 "http://www2.example.com",
366 "test-cookie",
367 kNoCookieHeader},
368
369 {"wss://www.example.com",
370 "https://www2.example.com",
371 "test-cookie",
372 kNoCookieHeader},
373
374 {"wss://www.example.com",
375 "ws://www2.example.com",
376 "test-cookie",
377 kNoCookieHeader},
378
379 {"wss://www.example.com",
380 "wss://www2.example.com",
381 "test-cookie",
382 kNoCookieHeader},
383};
384
385INSTANTIATE_TEST_CASE_P(WebSocketStreamClientUseCookieTest,
386 WebSocketStreamClientUseCookieTest,
387 ValuesIn(kClientUseCookieParameters));
388
389const ServerSetCookieParameter kServerSetCookieParameters[] = {
390 // Cookies coming from ws
391 {"ws://www.example.com",
392 "http://www.example.com",
393 "test-cookie",
394 "Set-Cookie: test-cookie"},
395
396 {"ws://www.example.com",
397 "https://www.example.com",
398 "test-cookie",
399 "Set-Cookie: test-cookie"},
400
401 {"ws://www.example.com",
402 "ws://www.example.com",
403 "test-cookie",
404 "Set-Cookie: test-cookie"},
405
406 {"ws://www.example.com",
407 "wss://www.example.com",
408 "test-cookie",
409 "Set-Cookie: test-cookie"},
410
411 // Cookies coming from wss
412 {"wss://www.example.com",
413 "http://www.example.com",
414 "test-cookie",
415 "Set-Cookie: test-cookie"},
416
417 {"wss://www.example.com",
418 "https://www.example.com",
419 "test-cookie",
420 "Set-Cookie: test-cookie"},
421
422 {"wss://www.example.com",
423 "ws://www.example.com",
424 "test-cookie",
425 "Set-Cookie: test-cookie"},
426
427 {"wss://www.example.com",
428 "wss://www.example.com",
429 "test-cookie",
430 "Set-Cookie: test-cookie"},
431
432 // cookies coming from ws (sharing domain)
433 {"ws://www.example.com",
434 "http://www2.example.com",
435 "test-cookie",
436 "Set-Cookie: test-cookie; Domain=example.com"},
437
438 {"ws://www.example.com",
439 "https://www2.example.com",
440 "test-cookie",
441 "Set-Cookie: test-cookie; Domain=example.com"},
442
443 {"ws://www.example.com",
444 "ws://www2.example.com",
445 "test-cookie",
446 "Set-Cookie: test-cookie; Domain=example.com"},
447
448 {"ws://www.example.com",
449 "wss://www2.example.com",
450 "test-cookie",
451 "Set-Cookie: test-cookie; Domain=example.com"},
452
453 // cookies coming from wss (sharing domain)
454 {"wss://www.example.com",
455 "http://www2.example.com",
456 "test-cookie",
457 "Set-Cookie: test-cookie; Domain=example.com"},
458
459 {"wss://www.example.com",
460 "https://www2.example.com",
461 "test-cookie",
462 "Set-Cookie: test-cookie; Domain=example.com"},
463
464 {"wss://www.example.com",
465 "ws://www2.example.com",
466 "test-cookie",
467 "Set-Cookie: test-cookie; Domain=example.com"},
468
469 {"wss://www.example.com",
470 "wss://www2.example.com",
471 "test-cookie",
472 "Set-Cookie: test-cookie; Domain=example.com"},
473
474 // Non-matching cookies coming from ws
475 {"ws://www.example.com",
476 "http://www2.example.com",
477 "",
478 "Set-Cookie: test-cookie"},
479
480 {"ws://www.example.com",
481 "https://www2.example.com",
482 "",
483 "Set-Cookie: test-cookie"},
484
485 {"ws://www.example.com",
486 "ws://www2.example.com",
487 "",
488 "Set-Cookie: test-cookie"},
489
490 {"ws://www.example.com",
491 "wss://www2.example.com",
492 "",
493 "Set-Cookie: test-cookie"},
494
495 // Non-matching cookies coming from wss
496 {"wss://www.example.com",
497 "http://www2.example.com",
498 "",
499 "Set-Cookie: test-cookie"},
500
501 {"wss://www.example.com",
502 "https://www2.example.com",
503 "",
504 "Set-Cookie: test-cookie"},
505
506 {"wss://www.example.com",
507 "ws://www2.example.com",
508 "",
509 "Set-Cookie: test-cookie"},
510
511 {"wss://www.example.com",
512 "wss://www2.example.com",
513 "",
514 "Set-Cookie: test-cookie"},
515};
516
517INSTANTIATE_TEST_CASE_P(WebSocketStreamServerSetCookieTest,
518 WebSocketStreamServerSetCookieTest,
519 ValuesIn(kServerSetCookieParameters));
520
521} // namespace
522} // namespace net