blob: 585e03d16811bfb63036843ec8606adc1464653a [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>
6
7#include "base/callback_forward.h"
danakj9c5cab52016-04-16 00:54:338#include "base/memory/ptr_util.h"
yhirano01a5d662015-02-12 04:33:069#include "base/memory/weak_ptr.h"
10#include "base/message_loop/message_loop.h"
11#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"
yhirano01a5d662015-02-12 04:33:0615#include "net/cookies/cookie_store.h"
16#include "net/socket/socket_test_util.h"
17#include "net/websockets/websocket_stream_create_test_base.h"
18#include "net/websockets/websocket_test_util.h"
19#include "testing/gtest/include/gtest/gtest.h"
20#include "url/gurl.h"
mkwst4997ce82015-07-25 12:00:0521#include "url/origin.h"
yhirano01a5d662015-02-12 04:33:0622
23namespace net {
24namespace {
25
26using ::testing::TestWithParam;
27using ::testing::ValuesIn;
28
29const char kNoCookieHeader[] = "";
30
31class TestBase : public WebSocketStreamCreateTestBase {
32 public:
33 void CreateAndConnect(const GURL& url,
mkwst4997ce82015-07-25 12:00:0534 const url::Origin& origin,
tyoshino8572d572016-07-13 06:29:4835 const GURL& first_party_for_cookies,
yhirano01a5d662015-02-12 04:33:0636 const std::string& cookie_header,
37 const std::string& response_body) {
38 // We assume cookie_header ends with CRLF if not empty, as
39 // WebSocketStandardRequestWithCookies requires. Use AddCRLFIfNotEmpty
40 // in a call site.
brettwa7ff1b292015-07-16 17:49:2941 CHECK(cookie_header.empty() ||
42 base::EndsWith(cookie_header, "\r\n", base::CompareCase::SENSITIVE));
yhirano01a5d662015-02-12 04:33:0643
44 url_request_context_host_.SetExpectations(
45 WebSocketStandardRequestWithCookies(url.path(), url.host(), origin,
alladacef397d2016-06-29 17:52:2346 cookie_header, std::string(),
47 std::string()),
yhirano01a5d662015-02-12 04:33:0648 response_body);
tyoshino8572d572016-07-13 06:29:4849 CreateAndConnectStream(url, NoSubProtocols(), origin,
50 first_party_for_cookies, "", nullptr);
yhirano01a5d662015-02-12 04:33:0651 }
52
53 std::string AddCRLFIfNotEmpty(const std::string& s) {
54 return s.empty() ? s : s + "\r\n";
55 }
56};
57
58struct ClientUseCookieParameter {
59 // The URL for the WebSocket connection.
60 const char* const url;
61 // The URL for the previously set cookies.
62 const char* const cookie_url;
63 // The previously set cookies contents.
64 const char* const cookie_line;
65 // The Cookie: HTTP header expected to appear in the WS request. An empty
66 // string means there is no Cookie: header.
67 const char* const cookie_header;
68};
69
70class WebSocketStreamClientUseCookieTest
71 : public TestBase,
72 public TestWithParam<ClientUseCookieParameter> {
73 public:
74 ~WebSocketStreamClientUseCookieTest() override {
75 // Permit any endpoint locks to be released.
76 stream_request_.reset();
77 stream_.reset();
78 base::RunLoop().RunUntilIdle();
79 }
80
81 static void SetCookieHelperFunction(const base::Closure& task,
82 base::WeakPtr<bool> weak_is_called,
83 base::WeakPtr<bool> weak_result,
84 bool success) {
85 *weak_is_called = true;
86 *weak_result = success;
87 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
88 }
89};
90
91struct ServerSetCookieParameter {
92 // The URL for the WebSocket connection.
93 const char* const url;
94 // The URL used to query cookies after the response received.
95 const char* const cookie_url;
96 // The cookies expected to appear for |cookie_url| inquiry.
97 const char* const cookie_line;
98 // The Set-Cookie: HTTP header attached to the response.
99 const char* const cookie_header;
100};
101
102class WebSocketStreamServerSetCookieTest
103 : public TestBase,
104 public TestWithParam<ServerSetCookieParameter> {
105 public:
106 ~WebSocketStreamServerSetCookieTest() override {
107 // Permit any endpoint locks to be released.
108 stream_request_.reset();
109 stream_.reset();
110 base::RunLoop().RunUntilIdle();
111 }
112
113 static void GetCookiesHelperFunction(const base::Closure& task,
114 base::WeakPtr<bool> weak_is_called,
115 base::WeakPtr<std::string> weak_result,
116 const std::string& cookies) {
117 *weak_is_called = true;
118 *weak_result = cookies;
119 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
120 }
121};
122
123TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) {
124 // For wss tests.
danakj9c5cab52016-04-16 00:54:33125 ssl_data_.push_back(base::WrapUnique(new SSLSocketDataProvider(ASYNC, OK)));
yhirano01a5d662015-02-12 04:33:06126
127 CookieStore* store =
128 url_request_context_host_.GetURLRequestContext()->cookie_store();
129
130 const GURL url(GetParam().url);
131 const GURL cookie_url(GetParam().cookie_url);
mkwst4997ce82015-07-25 12:00:05132 const url::Origin origin(GURL("http://www.example.com"));
tyoshino8572d572016-07-13 06:29:48133 const GURL first_party_for_cookies("http://www.example.com/");
yhirano01a5d662015-02-12 04:33:06134 const std::string cookie_line(GetParam().cookie_line);
135 const std::string cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header));
136
137 bool is_called = false;
138 bool set_cookie_result = false;
139 base::WeakPtrFactory<bool> weak_is_called(&is_called);
140 base::WeakPtrFactory<bool> weak_set_cookie_result(&set_cookie_result);
141
142 base::RunLoop run_loop;
143 store->SetCookieWithOptionsAsync(
144 cookie_url, cookie_line, CookieOptions(),
145 base::Bind(&SetCookieHelperFunction, run_loop.QuitClosure(),
146 weak_is_called.GetWeakPtr(),
147 weak_set_cookie_result.GetWeakPtr()));
148 run_loop.Run();
149 ASSERT_TRUE(is_called);
150 ASSERT_TRUE(set_cookie_result);
151
tyoshino8572d572016-07-13 06:29:48152 CreateAndConnect(url, origin, first_party_for_cookies, cookie_header,
153 WebSocketStandardResponse(""));
yhirano01a5d662015-02-12 04:33:06154 WaitUntilConnectDone();
155 EXPECT_FALSE(has_failed());
156}
157
158TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) {
159 // For wss tests.
danakj9c5cab52016-04-16 00:54:33160 ssl_data_.push_back(base::WrapUnique(new SSLSocketDataProvider(ASYNC, OK)));
yhirano01a5d662015-02-12 04:33:06161
162 const GURL url(GetParam().url);
163 const GURL cookie_url(GetParam().cookie_url);
mkwst4997ce82015-07-25 12:00:05164 const url::Origin origin(GURL("http://www.example.com"));
tyoshino8572d572016-07-13 06:29:48165 const GURL first_party_for_cookies("http://www.example.com/");
yhirano01a5d662015-02-12 04:33:06166 const std::string cookie_line(GetParam().cookie_line);
167 const std::string cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header));
168
169 const std::string response = base::StringPrintf(
170 "HTTP/1.1 101 Switching Protocols\r\n"
171 "Upgrade: websocket\r\n"
172 "Connection: Upgrade\r\n"
173 "%s"
174 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
175 "\r\n",
176 cookie_header.c_str());
177
178 CookieStore* store =
179 url_request_context_host_.GetURLRequestContext()->cookie_store();
180
tyoshino8572d572016-07-13 06:29:48181 CreateAndConnect(url, origin, first_party_for_cookies, "", response);
yhirano01a5d662015-02-12 04:33:06182 WaitUntilConnectDone();
183 EXPECT_FALSE(has_failed());
184
185 bool is_called = false;
186 std::string get_cookies_result;
187 base::WeakPtrFactory<bool> weak_is_called(&is_called);
188 base::WeakPtrFactory<std::string> weak_get_cookies_result(
189 &get_cookies_result);
190 base::RunLoop run_loop;
191 store->GetCookiesWithOptionsAsync(
192 cookie_url, CookieOptions(),
193 base::Bind(&GetCookiesHelperFunction, run_loop.QuitClosure(),
194 weak_is_called.GetWeakPtr(),
195 weak_get_cookies_result.GetWeakPtr()));
196 run_loop.Run();
197 EXPECT_TRUE(is_called);
198 EXPECT_EQ(cookie_line, get_cookies_result);
199}
200
201// Test parameters definitions follow...
202
203const ClientUseCookieParameter kClientUseCookieParameters[] = {
204 // Non-secure cookies for ws
205 {"ws://www.example.com",
206 "http://www.example.com",
207 "test-cookie",
208 "Cookie: test-cookie"},
209
210 {"ws://www.example.com",
211 "https://www.example.com",
212 "test-cookie",
213 "Cookie: test-cookie"},
214
215 {"ws://www.example.com",
216 "ws://www.example.com",
217 "test-cookie",
218 "Cookie: test-cookie"},
219
220 {"ws://www.example.com",
221 "wss://www.example.com",
222 "test-cookie",
223 "Cookie: test-cookie"},
224
225 // Non-secure cookies for wss
226 {"wss://www.example.com",
227 "http://www.example.com",
228 "test-cookie",
229 "Cookie: test-cookie"},
230
231 {"wss://www.example.com",
232 "https://www.example.com",
233 "test-cookie",
234 "Cookie: test-cookie"},
235
236 {"wss://www.example.com",
237 "ws://www.example.com",
238 "test-cookie",
239 "Cookie: test-cookie"},
240
241 {"wss://www.example.com",
242 "wss://www.example.com",
243 "test-cookie",
244 "Cookie: test-cookie"},
245
246 // Secure-cookies for ws
247 {"ws://www.example.com",
248 "https://www.example.com",
249 "test-cookie; secure",
250 kNoCookieHeader},
251
252 {"ws://www.example.com",
253 "wss://www.example.com",
254 "test-cookie; secure",
255 kNoCookieHeader},
256
257 // Secure-cookies for wss
258 {"wss://www.example.com",
259 "https://www.example.com",
260 "test-cookie; secure",
261 "Cookie: test-cookie"},
262
263 {"wss://www.example.com",
264 "wss://www.example.com",
265 "test-cookie; secure",
266 "Cookie: test-cookie"},
267
268 // Non-secure cookies for ws (sharing domain)
269 {"ws://www.example.com",
270 "http://www2.example.com",
271 "test-cookie; Domain=example.com",
272 "Cookie: test-cookie"},
273
274 {"ws://www.example.com",
275 "https://www2.example.com",
276 "test-cookie; Domain=example.com",
277 "Cookie: test-cookie"},
278
279 {"ws://www.example.com",
280 "ws://www2.example.com",
281 "test-cookie; Domain=example.com",
282 "Cookie: test-cookie"},
283
284 {"ws://www.example.com",
285 "wss://www2.example.com",
286 "test-cookie; Domain=example.com",
287 "Cookie: test-cookie"},
288
289 // Non-secure cookies for wss (sharing domain)
290 {"wss://www.example.com",
291 "http://www2.example.com",
292 "test-cookie; Domain=example.com",
293 "Cookie: test-cookie"},
294
295 {"wss://www.example.com",
296 "https://www2.example.com",
297 "test-cookie; Domain=example.com",
298 "Cookie: test-cookie"},
299
300 {"wss://www.example.com",
301 "ws://www2.example.com",
302 "test-cookie; Domain=example.com",
303 "Cookie: test-cookie"},
304
305 {"wss://www.example.com",
306 "wss://www2.example.com",
307 "test-cookie; Domain=example.com",
308 "Cookie: test-cookie"},
309
310 // Secure-cookies for ws (sharing domain)
311 {"ws://www.example.com",
312 "https://www2.example.com",
313 "test-cookie; Domain=example.com; secure",
314 kNoCookieHeader},
315
316 {"ws://www.example.com",
317 "wss://www2.example.com",
318 "test-cookie; Domain=example.com; secure",
319 kNoCookieHeader},
320
321 // Secure-cookies for wss (sharing domain)
322 {"wss://www.example.com",
323 "https://www2.example.com",
324 "test-cookie; Domain=example.com; secure",
325 "Cookie: test-cookie"},
326
327 {"wss://www.example.com",
328 "wss://www2.example.com",
329 "test-cookie; Domain=example.com; secure",
330 "Cookie: test-cookie"},
331
332 // Non-matching cookies for ws
333 {"ws://www.example.com",
334 "http://www2.example.com",
335 "test-cookie",
336 kNoCookieHeader},
337
338 {"ws://www.example.com",
339 "https://www2.example.com",
340 "test-cookie",
341 kNoCookieHeader},
342
343 {"ws://www.example.com",
344 "ws://www2.example.com",
345 "test-cookie",
346 kNoCookieHeader},
347
348 {"ws://www.example.com",
349 "wss://www2.example.com",
350 "test-cookie",
351 kNoCookieHeader},
352
353 // Non-matching cookies for wss
354 {"wss://www.example.com",
355 "http://www2.example.com",
356 "test-cookie",
357 kNoCookieHeader},
358
359 {"wss://www.example.com",
360 "https://www2.example.com",
361 "test-cookie",
362 kNoCookieHeader},
363
364 {"wss://www.example.com",
365 "ws://www2.example.com",
366 "test-cookie",
367 kNoCookieHeader},
368
369 {"wss://www.example.com",
370 "wss://www2.example.com",
371 "test-cookie",
372 kNoCookieHeader},
373};
374
375INSTANTIATE_TEST_CASE_P(WebSocketStreamClientUseCookieTest,
376 WebSocketStreamClientUseCookieTest,
377 ValuesIn(kClientUseCookieParameters));
378
379const ServerSetCookieParameter kServerSetCookieParameters[] = {
380 // Cookies coming from ws
381 {"ws://www.example.com",
382 "http://www.example.com",
383 "test-cookie",
384 "Set-Cookie: test-cookie"},
385
386 {"ws://www.example.com",
387 "https://www.example.com",
388 "test-cookie",
389 "Set-Cookie: test-cookie"},
390
391 {"ws://www.example.com",
392 "ws://www.example.com",
393 "test-cookie",
394 "Set-Cookie: test-cookie"},
395
396 {"ws://www.example.com",
397 "wss://www.example.com",
398 "test-cookie",
399 "Set-Cookie: test-cookie"},
400
401 // Cookies coming from wss
402 {"wss://www.example.com",
403 "http://www.example.com",
404 "test-cookie",
405 "Set-Cookie: test-cookie"},
406
407 {"wss://www.example.com",
408 "https://www.example.com",
409 "test-cookie",
410 "Set-Cookie: test-cookie"},
411
412 {"wss://www.example.com",
413 "ws://www.example.com",
414 "test-cookie",
415 "Set-Cookie: test-cookie"},
416
417 {"wss://www.example.com",
418 "wss://www.example.com",
419 "test-cookie",
420 "Set-Cookie: test-cookie"},
421
422 // cookies coming from ws (sharing domain)
423 {"ws://www.example.com",
424 "http://www2.example.com",
425 "test-cookie",
426 "Set-Cookie: test-cookie; Domain=example.com"},
427
428 {"ws://www.example.com",
429 "https://www2.example.com",
430 "test-cookie",
431 "Set-Cookie: test-cookie; Domain=example.com"},
432
433 {"ws://www.example.com",
434 "ws://www2.example.com",
435 "test-cookie",
436 "Set-Cookie: test-cookie; Domain=example.com"},
437
438 {"ws://www.example.com",
439 "wss://www2.example.com",
440 "test-cookie",
441 "Set-Cookie: test-cookie; Domain=example.com"},
442
443 // cookies coming from wss (sharing domain)
444 {"wss://www.example.com",
445 "http://www2.example.com",
446 "test-cookie",
447 "Set-Cookie: test-cookie; Domain=example.com"},
448
449 {"wss://www.example.com",
450 "https://www2.example.com",
451 "test-cookie",
452 "Set-Cookie: test-cookie; Domain=example.com"},
453
454 {"wss://www.example.com",
455 "ws://www2.example.com",
456 "test-cookie",
457 "Set-Cookie: test-cookie; Domain=example.com"},
458
459 {"wss://www.example.com",
460 "wss://www2.example.com",
461 "test-cookie",
462 "Set-Cookie: test-cookie; Domain=example.com"},
463
464 // Non-matching cookies coming from ws
465 {"ws://www.example.com",
466 "http://www2.example.com",
467 "",
468 "Set-Cookie: test-cookie"},
469
470 {"ws://www.example.com",
471 "https://www2.example.com",
472 "",
473 "Set-Cookie: test-cookie"},
474
475 {"ws://www.example.com",
476 "ws://www2.example.com",
477 "",
478 "Set-Cookie: test-cookie"},
479
480 {"ws://www.example.com",
481 "wss://www2.example.com",
482 "",
483 "Set-Cookie: test-cookie"},
484
485 // Non-matching cookies coming from wss
486 {"wss://www.example.com",
487 "http://www2.example.com",
488 "",
489 "Set-Cookie: test-cookie"},
490
491 {"wss://www.example.com",
492 "https://www2.example.com",
493 "",
494 "Set-Cookie: test-cookie"},
495
496 {"wss://www.example.com",
497 "ws://www2.example.com",
498 "",
499 "Set-Cookie: test-cookie"},
500
501 {"wss://www.example.com",
502 "wss://www2.example.com",
503 "",
504 "Set-Cookie: test-cookie"},
505};
506
507INSTANTIATE_TEST_CASE_P(WebSocketStreamServerSetCookieTest,
508 WebSocketStreamServerSetCookieTest,
509 ValuesIn(kServerSetCookieParameters));
510
511} // namespace
512} // namespace net