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() || EndsWith(cookie_header
, "\r\n", true));
40 url_request_context_host_
.SetExpectations(
41 WebSocketStandardRequestWithCookies(url
.path(), url
.host(), origin
,
42 cookie_header
, std::string()),
44 CreateAndConnectStream(url
.spec(), NoSubProtocols(), origin
, nullptr);
47 std::string
AddCRLFIfNotEmpty(const std::string
& s
) {
48 return s
.empty() ? s
: s
+ "\r\n";
52 struct ClientUseCookieParameter
{
53 // The URL for the WebSocket connection.
54 const char* const url
;
55 // The URL for the previously set cookies.
56 const char* const cookie_url
;
57 // The previously set cookies contents.
58 const char* const cookie_line
;
59 // The Cookie: HTTP header expected to appear in the WS request. An empty
60 // string means there is no Cookie: header.
61 const char* const cookie_header
;
64 class WebSocketStreamClientUseCookieTest
66 public TestWithParam
<ClientUseCookieParameter
> {
68 ~WebSocketStreamClientUseCookieTest() override
{
69 // Permit any endpoint locks to be released.
70 stream_request_
.reset();
72 base::RunLoop().RunUntilIdle();
75 static void SetCookieHelperFunction(const base::Closure
& task
,
76 base::WeakPtr
<bool> weak_is_called
,
77 base::WeakPtr
<bool> weak_result
,
79 *weak_is_called
= true;
80 *weak_result
= success
;
81 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, task
);
85 struct ServerSetCookieParameter
{
86 // The URL for the WebSocket connection.
87 const char* const url
;
88 // The URL used to query cookies after the response received.
89 const char* const cookie_url
;
90 // The cookies expected to appear for |cookie_url| inquiry.
91 const char* const cookie_line
;
92 // The Set-Cookie: HTTP header attached to the response.
93 const char* const cookie_header
;
96 class WebSocketStreamServerSetCookieTest
98 public TestWithParam
<ServerSetCookieParameter
> {
100 ~WebSocketStreamServerSetCookieTest() override
{
101 // Permit any endpoint locks to be released.
102 stream_request_
.reset();
104 base::RunLoop().RunUntilIdle();
107 static void GetCookiesHelperFunction(const base::Closure
& task
,
108 base::WeakPtr
<bool> weak_is_called
,
109 base::WeakPtr
<std::string
> weak_result
,
110 const std::string
& cookies
) {
111 *weak_is_called
= true;
112 *weak_result
= cookies
;
113 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, task
);
117 TEST_P(WebSocketStreamClientUseCookieTest
, ClientUseCookie
) {
119 ssl_data_
.push_back(new SSLSocketDataProvider(ASYNC
, OK
));
122 url_request_context_host_
.GetURLRequestContext()->cookie_store();
124 const GURL
url(GetParam().url
);
125 const GURL
cookie_url(GetParam().cookie_url
);
126 const std::string
origin("http://www.example.com");
127 const std::string
cookie_line(GetParam().cookie_line
);
128 const std::string
cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header
));
130 bool is_called
= false;
131 bool set_cookie_result
= false;
132 base::WeakPtrFactory
<bool> weak_is_called(&is_called
);
133 base::WeakPtrFactory
<bool> weak_set_cookie_result(&set_cookie_result
);
135 base::RunLoop run_loop
;
136 store
->SetCookieWithOptionsAsync(
137 cookie_url
, cookie_line
, CookieOptions(),
138 base::Bind(&SetCookieHelperFunction
, run_loop
.QuitClosure(),
139 weak_is_called
.GetWeakPtr(),
140 weak_set_cookie_result
.GetWeakPtr()));
142 ASSERT_TRUE(is_called
);
143 ASSERT_TRUE(set_cookie_result
);
145 CreateAndConnect(url
, origin
, cookie_header
, WebSocketStandardResponse(""));
146 WaitUntilConnectDone();
147 EXPECT_FALSE(has_failed());
150 TEST_P(WebSocketStreamServerSetCookieTest
, ServerSetCookie
) {
152 ssl_data_
.push_back(new SSLSocketDataProvider(ASYNC
, OK
));
154 const GURL
url(GetParam().url
);
155 const GURL
cookie_url(GetParam().cookie_url
);
156 const std::string
origin("http://www.example.com");
157 const std::string
cookie_line(GetParam().cookie_line
);
158 const std::string
cookie_header(AddCRLFIfNotEmpty(GetParam().cookie_header
));
160 const std::string response
= base::StringPrintf(
161 "HTTP/1.1 101 Switching Protocols\r\n"
162 "Upgrade: websocket\r\n"
163 "Connection: Upgrade\r\n"
165 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
167 cookie_header
.c_str());
170 url_request_context_host_
.GetURLRequestContext()->cookie_store();
172 CreateAndConnect(url
, origin
, "", response
);
173 WaitUntilConnectDone();
174 EXPECT_FALSE(has_failed());
176 bool is_called
= false;
177 std::string get_cookies_result
;
178 base::WeakPtrFactory
<bool> weak_is_called(&is_called
);
179 base::WeakPtrFactory
<std::string
> weak_get_cookies_result(
180 &get_cookies_result
);
181 base::RunLoop run_loop
;
182 store
->GetCookiesWithOptionsAsync(
183 cookie_url
, CookieOptions(),
184 base::Bind(&GetCookiesHelperFunction
, run_loop
.QuitClosure(),
185 weak_is_called
.GetWeakPtr(),
186 weak_get_cookies_result
.GetWeakPtr()));
188 EXPECT_TRUE(is_called
);
189 EXPECT_EQ(cookie_line
, get_cookies_result
);
192 // Test parameters definitions follow...
194 const ClientUseCookieParameter kClientUseCookieParameters
[] = {
195 // Non-secure cookies for ws
196 {"ws://www.example.com",
197 "http://www.example.com",
199 "Cookie: test-cookie"},
201 {"ws://www.example.com",
202 "https://www.example.com",
204 "Cookie: test-cookie"},
206 {"ws://www.example.com",
207 "ws://www.example.com",
209 "Cookie: test-cookie"},
211 {"ws://www.example.com",
212 "wss://www.example.com",
214 "Cookie: test-cookie"},
216 // Non-secure cookies for wss
217 {"wss://www.example.com",
218 "http://www.example.com",
220 "Cookie: test-cookie"},
222 {"wss://www.example.com",
223 "https://www.example.com",
225 "Cookie: test-cookie"},
227 {"wss://www.example.com",
228 "ws://www.example.com",
230 "Cookie: test-cookie"},
232 {"wss://www.example.com",
233 "wss://www.example.com",
235 "Cookie: test-cookie"},
237 // Secure-cookies for ws
238 {"ws://www.example.com",
239 "https://www.example.com",
240 "test-cookie; secure",
243 {"ws://www.example.com",
244 "wss://www.example.com",
245 "test-cookie; secure",
248 // Secure-cookies for wss
249 {"wss://www.example.com",
250 "https://www.example.com",
251 "test-cookie; secure",
252 "Cookie: test-cookie"},
254 {"wss://www.example.com",
255 "wss://www.example.com",
256 "test-cookie; secure",
257 "Cookie: test-cookie"},
259 // Non-secure cookies for ws (sharing domain)
260 {"ws://www.example.com",
261 "http://www2.example.com",
262 "test-cookie; Domain=example.com",
263 "Cookie: test-cookie"},
265 {"ws://www.example.com",
266 "https://www2.example.com",
267 "test-cookie; Domain=example.com",
268 "Cookie: test-cookie"},
270 {"ws://www.example.com",
271 "ws://www2.example.com",
272 "test-cookie; Domain=example.com",
273 "Cookie: test-cookie"},
275 {"ws://www.example.com",
276 "wss://www2.example.com",
277 "test-cookie; Domain=example.com",
278 "Cookie: test-cookie"},
280 // Non-secure cookies for wss (sharing domain)
281 {"wss://www.example.com",
282 "http://www2.example.com",
283 "test-cookie; Domain=example.com",
284 "Cookie: test-cookie"},
286 {"wss://www.example.com",
287 "https://www2.example.com",
288 "test-cookie; Domain=example.com",
289 "Cookie: test-cookie"},
291 {"wss://www.example.com",
292 "ws://www2.example.com",
293 "test-cookie; Domain=example.com",
294 "Cookie: test-cookie"},
296 {"wss://www.example.com",
297 "wss://www2.example.com",
298 "test-cookie; Domain=example.com",
299 "Cookie: test-cookie"},
301 // Secure-cookies for ws (sharing domain)
302 {"ws://www.example.com",
303 "https://www2.example.com",
304 "test-cookie; Domain=example.com; secure",
307 {"ws://www.example.com",
308 "wss://www2.example.com",
309 "test-cookie; Domain=example.com; secure",
312 // Secure-cookies for wss (sharing domain)
313 {"wss://www.example.com",
314 "https://www2.example.com",
315 "test-cookie; Domain=example.com; secure",
316 "Cookie: test-cookie"},
318 {"wss://www.example.com",
319 "wss://www2.example.com",
320 "test-cookie; Domain=example.com; secure",
321 "Cookie: test-cookie"},
323 // Non-matching cookies for ws
324 {"ws://www.example.com",
325 "http://www2.example.com",
329 {"ws://www.example.com",
330 "https://www2.example.com",
334 {"ws://www.example.com",
335 "ws://www2.example.com",
339 {"ws://www.example.com",
340 "wss://www2.example.com",
344 // Non-matching cookies for wss
345 {"wss://www.example.com",
346 "http://www2.example.com",
350 {"wss://www.example.com",
351 "https://www2.example.com",
355 {"wss://www.example.com",
356 "ws://www2.example.com",
360 {"wss://www.example.com",
361 "wss://www2.example.com",
366 INSTANTIATE_TEST_CASE_P(WebSocketStreamClientUseCookieTest
,
367 WebSocketStreamClientUseCookieTest
,
368 ValuesIn(kClientUseCookieParameters
));
370 const ServerSetCookieParameter kServerSetCookieParameters
[] = {
371 // Cookies coming from ws
372 {"ws://www.example.com",
373 "http://www.example.com",
375 "Set-Cookie: test-cookie"},
377 {"ws://www.example.com",
378 "https://www.example.com",
380 "Set-Cookie: test-cookie"},
382 {"ws://www.example.com",
383 "ws://www.example.com",
385 "Set-Cookie: test-cookie"},
387 {"ws://www.example.com",
388 "wss://www.example.com",
390 "Set-Cookie: test-cookie"},
392 // Cookies coming from wss
393 {"wss://www.example.com",
394 "http://www.example.com",
396 "Set-Cookie: test-cookie"},
398 {"wss://www.example.com",
399 "https://www.example.com",
401 "Set-Cookie: test-cookie"},
403 {"wss://www.example.com",
404 "ws://www.example.com",
406 "Set-Cookie: test-cookie"},
408 {"wss://www.example.com",
409 "wss://www.example.com",
411 "Set-Cookie: test-cookie"},
413 // cookies coming from ws (sharing domain)
414 {"ws://www.example.com",
415 "http://www2.example.com",
417 "Set-Cookie: test-cookie; Domain=example.com"},
419 {"ws://www.example.com",
420 "https://www2.example.com",
422 "Set-Cookie: test-cookie; Domain=example.com"},
424 {"ws://www.example.com",
425 "ws://www2.example.com",
427 "Set-Cookie: test-cookie; Domain=example.com"},
429 {"ws://www.example.com",
430 "wss://www2.example.com",
432 "Set-Cookie: test-cookie; Domain=example.com"},
434 // cookies coming from wss (sharing domain)
435 {"wss://www.example.com",
436 "http://www2.example.com",
438 "Set-Cookie: test-cookie; Domain=example.com"},
440 {"wss://www.example.com",
441 "https://www2.example.com",
443 "Set-Cookie: test-cookie; Domain=example.com"},
445 {"wss://www.example.com",
446 "ws://www2.example.com",
448 "Set-Cookie: test-cookie; Domain=example.com"},
450 {"wss://www.example.com",
451 "wss://www2.example.com",
453 "Set-Cookie: test-cookie; Domain=example.com"},
455 // Non-matching cookies coming from ws
456 {"ws://www.example.com",
457 "http://www2.example.com",
459 "Set-Cookie: test-cookie"},
461 {"ws://www.example.com",
462 "https://www2.example.com",
464 "Set-Cookie: test-cookie"},
466 {"ws://www.example.com",
467 "ws://www2.example.com",
469 "Set-Cookie: test-cookie"},
471 {"ws://www.example.com",
472 "wss://www2.example.com",
474 "Set-Cookie: test-cookie"},
476 // Non-matching cookies coming from wss
477 {"wss://www.example.com",
478 "http://www2.example.com",
480 "Set-Cookie: test-cookie"},
482 {"wss://www.example.com",
483 "https://www2.example.com",
485 "Set-Cookie: test-cookie"},
487 {"wss://www.example.com",
488 "ws://www2.example.com",
490 "Set-Cookie: test-cookie"},
492 {"wss://www.example.com",
493 "wss://www2.example.com",
495 "Set-Cookie: test-cookie"},
498 INSTANTIATE_TEST_CASE_P(WebSocketStreamServerSetCookieTest
,
499 WebSocketStreamServerSetCookieTest
,
500 ValuesIn(kServerSetCookieParameters
));