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