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