1 // 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.
7 #include "base/callback_forward.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "net/cookies/cookie_store.h"
15 #include "net/socket/socket_test_util.h"
16 #include "net/websockets/websocket_stream_create_test_base.h"
17 #include "net/websockets/websocket_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
24 using ::testing::TestWithParam
;
25 using ::testing::ValuesIn
;
27 const char kNoCookieHeader
[] = "";
29 class TestBase
: public WebSocketStreamCreateTestBase
{
31 void CreateAndConnect(const GURL
& url
,
32 const std::string
& origin
,
33 const std::string
& cookie_header
,
34 const std::string
& response_body
) {
35 // We assume cookie_header ends with CRLF if not empty, as
36 // WebSocketStandardRequestWithCookies requires. Use AddCRLFIfNotEmpty
38 CHECK(cookie_header
.empty() ||
39 base::EndsWith(cookie_header
, "\r\n", base::CompareCase::SENSITIVE
));
41 url_request_context_host_
.SetExpectations(
42 WebSocketStandardRequestWithCookies(url
.path(), url
.host(), origin
,
43 cookie_header
, std::string()),
45 CreateAndConnectStream(url
.spec(), NoSubProtocols(), origin
, nullptr);
48 std::string
AddCRLFIfNotEmpty(const std::string
& s
) {
49 return s
.empty() ? s
: s
+ "\r\n";
53 struct ClientUseCookieParameter
{
54 // The URL for the WebSocket connection.
55 const char* const url
;
56 // The URL for the previously set cookies.
57 const char* const cookie_url
;
58 // The previously set cookies contents.
59 const char* const cookie_line
;
60 // The Cookie: HTTP header expected to appear in the WS request. An empty
61 // string means there is no Cookie: header.
62 const char* const cookie_header
;
65 class WebSocketStreamClientUseCookieTest
67 public TestWithParam
<ClientUseCookieParameter
> {
69 ~WebSocketStreamClientUseCookieTest() override
{
70 // Permit any endpoint locks to be released.
71 stream_request_
.reset();
73 base::RunLoop().RunUntilIdle();
76 static void SetCookieHelperFunction(const base::Closure
& task
,
77 base::WeakPtr
<bool> weak_is_called
,
78 base::WeakPtr
<bool> weak_result
,
80 *weak_is_called
= true;
81 *weak_result
= success
;
82 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, task
);
86 struct ServerSetCookieParameter
{
87 // The URL for the WebSocket connection.
88 const char* const url
;
89 // The URL used to query cookies after the response received.
90 const char* const cookie_url
;
91 // The cookies expected to appear for |cookie_url| inquiry.
92 const char* const cookie_line
;
93 // The Set-Cookie: HTTP header attached to the response.
94 const char* const cookie_header
;
97 class WebSocketStreamServerSetCookieTest
99 public TestWithParam
<ServerSetCookieParameter
> {
101 ~WebSocketStreamServerSetCookieTest() override
{
102 // Permit any endpoint locks to be released.
103 stream_request_
.reset();
105 base::RunLoop().RunUntilIdle();
108 static void GetCookiesHelperFunction(const base::Closure
& task
,
109 base::WeakPtr
<bool> weak_is_called
,
110 base::WeakPtr
<std::string
> weak_result
,
111 const std::string
& cookies
) {
112 *weak_is_called
= true;
113 *weak_result
= cookies
;
114 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, task
);
118 TEST_P(WebSocketStreamClientUseCookieTest
, ClientUseCookie
) {
120 ssl_data_
.push_back(new SSLSocketDataProvider(ASYNC
, OK
));
123 url_request_context_host_
.GetURLRequestContext()->cookie_store();
125 const GURL
url(GetParam().url
);
126 const GURL
cookie_url(GetParam().cookie_url
);
127 const std::string
origin("http://www.example.com");
128 const std::string
cookie_line(GetParam().cookie_line
);
129 const std::string
cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header
));
131 bool is_called
= false;
132 bool set_cookie_result
= false;
133 base::WeakPtrFactory
<bool> weak_is_called(&is_called
);
134 base::WeakPtrFactory
<bool> weak_set_cookie_result(&set_cookie_result
);
136 base::RunLoop run_loop
;
137 store
->SetCookieWithOptionsAsync(
138 cookie_url
, cookie_line
, CookieOptions(),
139 base::Bind(&SetCookieHelperFunction
, run_loop
.QuitClosure(),
140 weak_is_called
.GetWeakPtr(),
141 weak_set_cookie_result
.GetWeakPtr()));
143 ASSERT_TRUE(is_called
);
144 ASSERT_TRUE(set_cookie_result
);
146 CreateAndConnect(url
, origin
, cookie_header
, WebSocketStandardResponse(""));
147 WaitUntilConnectDone();
148 EXPECT_FALSE(has_failed());
151 TEST_P(WebSocketStreamServerSetCookieTest
, ServerSetCookie
) {
153 ssl_data_
.push_back(new SSLSocketDataProvider(ASYNC
, OK
));
155 const GURL
url(GetParam().url
);
156 const GURL
cookie_url(GetParam().cookie_url
);
157 const std::string
origin("http://www.example.com");
158 const std::string
cookie_line(GetParam().cookie_line
);
159 const std::string
cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header
));
161 const std::string response
= base::StringPrintf(
162 "HTTP/1.1 101 Switching Protocols\r\n"
163 "Upgrade: websocket\r\n"
164 "Connection: Upgrade\r\n"
166 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
168 cookie_header
.c_str());
171 url_request_context_host_
.GetURLRequestContext()->cookie_store();
173 CreateAndConnect(url
, origin
, "", response
);
174 WaitUntilConnectDone();
175 EXPECT_FALSE(has_failed());
177 bool is_called
= false;
178 std::string get_cookies_result
;
179 base::WeakPtrFactory
<bool> weak_is_called(&is_called
);
180 base::WeakPtrFactory
<std::string
> weak_get_cookies_result(
181 &get_cookies_result
);
182 base::RunLoop run_loop
;
183 store
->GetCookiesWithOptionsAsync(
184 cookie_url
, CookieOptions(),
185 base::Bind(&GetCookiesHelperFunction
, run_loop
.QuitClosure(),
186 weak_is_called
.GetWeakPtr(),
187 weak_get_cookies_result
.GetWeakPtr()));
189 EXPECT_TRUE(is_called
);
190 EXPECT_EQ(cookie_line
, get_cookies_result
);
193 // Test parameters definitions follow...
195 const ClientUseCookieParameter kClientUseCookieParameters
[] = {
196 // Non-secure cookies for ws
197 {"ws://www.example.com",
198 "http://www.example.com",
200 "Cookie: test-cookie"},
202 {"ws://www.example.com",
203 "https://www.example.com",
205 "Cookie: test-cookie"},
207 {"ws://www.example.com",
208 "ws://www.example.com",
210 "Cookie: test-cookie"},
212 {"ws://www.example.com",
213 "wss://www.example.com",
215 "Cookie: test-cookie"},
217 // Non-secure cookies for wss
218 {"wss://www.example.com",
219 "http://www.example.com",
221 "Cookie: test-cookie"},
223 {"wss://www.example.com",
224 "https://www.example.com",
226 "Cookie: test-cookie"},
228 {"wss://www.example.com",
229 "ws://www.example.com",
231 "Cookie: test-cookie"},
233 {"wss://www.example.com",
234 "wss://www.example.com",
236 "Cookie: test-cookie"},
238 // Secure-cookies for ws
239 {"ws://www.example.com",
240 "https://www.example.com",
241 "test-cookie; secure",
244 {"ws://www.example.com",
245 "wss://www.example.com",
246 "test-cookie; secure",
249 // Secure-cookies for wss
250 {"wss://www.example.com",
251 "https://www.example.com",
252 "test-cookie; secure",
253 "Cookie: test-cookie"},
255 {"wss://www.example.com",
256 "wss://www.example.com",
257 "test-cookie; secure",
258 "Cookie: test-cookie"},
260 // Non-secure cookies for ws (sharing domain)
261 {"ws://www.example.com",
262 "http://www2.example.com",
263 "test-cookie; Domain=example.com",
264 "Cookie: test-cookie"},
266 {"ws://www.example.com",
267 "https://www2.example.com",
268 "test-cookie; Domain=example.com",
269 "Cookie: test-cookie"},
271 {"ws://www.example.com",
272 "ws://www2.example.com",
273 "test-cookie; Domain=example.com",
274 "Cookie: test-cookie"},
276 {"ws://www.example.com",
277 "wss://www2.example.com",
278 "test-cookie; Domain=example.com",
279 "Cookie: test-cookie"},
281 // Non-secure cookies for wss (sharing domain)
282 {"wss://www.example.com",
283 "http://www2.example.com",
284 "test-cookie; Domain=example.com",
285 "Cookie: test-cookie"},
287 {"wss://www.example.com",
288 "https://www2.example.com",
289 "test-cookie; Domain=example.com",
290 "Cookie: test-cookie"},
292 {"wss://www.example.com",
293 "ws://www2.example.com",
294 "test-cookie; Domain=example.com",
295 "Cookie: test-cookie"},
297 {"wss://www.example.com",
298 "wss://www2.example.com",
299 "test-cookie; Domain=example.com",
300 "Cookie: test-cookie"},
302 // Secure-cookies for ws (sharing domain)
303 {"ws://www.example.com",
304 "https://www2.example.com",
305 "test-cookie; Domain=example.com; secure",
308 {"ws://www.example.com",
309 "wss://www2.example.com",
310 "test-cookie; Domain=example.com; secure",
313 // Secure-cookies for wss (sharing domain)
314 {"wss://www.example.com",
315 "https://www2.example.com",
316 "test-cookie; Domain=example.com; secure",
317 "Cookie: test-cookie"},
319 {"wss://www.example.com",
320 "wss://www2.example.com",
321 "test-cookie; Domain=example.com; secure",
322 "Cookie: test-cookie"},
324 // Non-matching cookies for ws
325 {"ws://www.example.com",
326 "http://www2.example.com",
330 {"ws://www.example.com",
331 "https://www2.example.com",
335 {"ws://www.example.com",
336 "ws://www2.example.com",
340 {"ws://www.example.com",
341 "wss://www2.example.com",
345 // Non-matching cookies for wss
346 {"wss://www.example.com",
347 "http://www2.example.com",
351 {"wss://www.example.com",
352 "https://www2.example.com",
356 {"wss://www.example.com",
357 "ws://www2.example.com",
361 {"wss://www.example.com",
362 "wss://www2.example.com",
367 INSTANTIATE_TEST_CASE_P(WebSocketStreamClientUseCookieTest
,
368 WebSocketStreamClientUseCookieTest
,
369 ValuesIn(kClientUseCookieParameters
));
371 const ServerSetCookieParameter kServerSetCookieParameters
[] = {
372 // Cookies coming from ws
373 {"ws://www.example.com",
374 "http://www.example.com",
376 "Set-Cookie: test-cookie"},
378 {"ws://www.example.com",
379 "https://www.example.com",
381 "Set-Cookie: test-cookie"},
383 {"ws://www.example.com",
384 "ws://www.example.com",
386 "Set-Cookie: test-cookie"},
388 {"ws://www.example.com",
389 "wss://www.example.com",
391 "Set-Cookie: test-cookie"},
393 // Cookies coming from wss
394 {"wss://www.example.com",
395 "http://www.example.com",
397 "Set-Cookie: test-cookie"},
399 {"wss://www.example.com",
400 "https://www.example.com",
402 "Set-Cookie: test-cookie"},
404 {"wss://www.example.com",
405 "ws://www.example.com",
407 "Set-Cookie: test-cookie"},
409 {"wss://www.example.com",
410 "wss://www.example.com",
412 "Set-Cookie: test-cookie"},
414 // cookies coming from ws (sharing domain)
415 {"ws://www.example.com",
416 "http://www2.example.com",
418 "Set-Cookie: test-cookie; Domain=example.com"},
420 {"ws://www.example.com",
421 "https://www2.example.com",
423 "Set-Cookie: test-cookie; Domain=example.com"},
425 {"ws://www.example.com",
426 "ws://www2.example.com",
428 "Set-Cookie: test-cookie; Domain=example.com"},
430 {"ws://www.example.com",
431 "wss://www2.example.com",
433 "Set-Cookie: test-cookie; Domain=example.com"},
435 // cookies coming from wss (sharing domain)
436 {"wss://www.example.com",
437 "http://www2.example.com",
439 "Set-Cookie: test-cookie; Domain=example.com"},
441 {"wss://www.example.com",
442 "https://www2.example.com",
444 "Set-Cookie: test-cookie; Domain=example.com"},
446 {"wss://www.example.com",
447 "ws://www2.example.com",
449 "Set-Cookie: test-cookie; Domain=example.com"},
451 {"wss://www.example.com",
452 "wss://www2.example.com",
454 "Set-Cookie: test-cookie; Domain=example.com"},
456 // Non-matching cookies coming from ws
457 {"ws://www.example.com",
458 "http://www2.example.com",
460 "Set-Cookie: test-cookie"},
462 {"ws://www.example.com",
463 "https://www2.example.com",
465 "Set-Cookie: test-cookie"},
467 {"ws://www.example.com",
468 "ws://www2.example.com",
470 "Set-Cookie: test-cookie"},
472 {"ws://www.example.com",
473 "wss://www2.example.com",
475 "Set-Cookie: test-cookie"},
477 // Non-matching cookies coming from wss
478 {"wss://www.example.com",
479 "http://www2.example.com",
481 "Set-Cookie: test-cookie"},
483 {"wss://www.example.com",
484 "https://www2.example.com",
486 "Set-Cookie: test-cookie"},
488 {"wss://www.example.com",
489 "ws://www2.example.com",
491 "Set-Cookie: test-cookie"},
493 {"wss://www.example.com",
494 "wss://www2.example.com",
496 "Set-Cookie: test-cookie"},
499 INSTANTIATE_TEST_CASE_P(WebSocketStreamServerSetCookieTest
,
500 WebSocketStreamServerSetCookieTest
,
501 ValuesIn(kServerSetCookieParameters
));