OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include <string> |
| 6 |
| 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" |
| 19 #include "url/gurl.h" |
| 20 |
| 21 namespace net { |
| 22 namespace { |
| 23 |
| 24 using ::testing::TestWithParam; |
| 25 using ::testing::ValuesIn; |
| 26 |
| 27 const char kNoCookieHeader[] = ""; |
| 28 |
| 29 class TestBase : public WebSocketStreamCreateTestBase { |
| 30 public: |
| 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 |
| 37 // in a call site. |
| 38 CHECK(cookie_header.empty() || EndsWith(cookie_header, "\r\n", true)); |
| 39 |
| 40 url_request_context_host_.SetExpectations( |
| 41 WebSocketStandardRequestWithCookies(url.path(), url.host(), origin, |
| 42 cookie_header, std::string()), |
| 43 response_body); |
| 44 CreateAndConnectStream(url.spec(), NoSubProtocols(), origin, nullptr); |
| 45 } |
| 46 |
| 47 std::string AddCRLFIfNotEmpty(const std::string& s) { |
| 48 return s.empty() ? s : s + "\r\n"; |
| 49 } |
| 50 }; |
| 51 |
| 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; |
| 62 }; |
| 63 |
| 64 class WebSocketStreamClientUseCookieTest |
| 65 : public TestBase, |
| 66 public TestWithParam<ClientUseCookieParameter> { |
| 67 public: |
| 68 ~WebSocketStreamClientUseCookieTest() override { |
| 69 // Permit any endpoint locks to be released. |
| 70 stream_request_.reset(); |
| 71 stream_.reset(); |
| 72 base::RunLoop().RunUntilIdle(); |
| 73 } |
| 74 |
| 75 static void SetCookieHelperFunction(const base::Closure& task, |
| 76 base::WeakPtr<bool> weak_is_called, |
| 77 base::WeakPtr<bool> weak_result, |
| 78 bool success) { |
| 79 *weak_is_called = true; |
| 80 *weak_result = success; |
| 81 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); |
| 82 } |
| 83 }; |
| 84 |
| 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; |
| 94 }; |
| 95 |
| 96 class WebSocketStreamServerSetCookieTest |
| 97 : public TestBase, |
| 98 public TestWithParam<ServerSetCookieParameter> { |
| 99 public: |
| 100 ~WebSocketStreamServerSetCookieTest() override { |
| 101 // Permit any endpoint locks to be released. |
| 102 stream_request_.reset(); |
| 103 stream_.reset(); |
| 104 base::RunLoop().RunUntilIdle(); |
| 105 } |
| 106 |
| 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); |
| 114 } |
| 115 }; |
| 116 |
| 117 TEST_P(WebSocketStreamClientUseCookieTest, ClientUseCookie) { |
| 118 // For wss tests. |
| 119 ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK)); |
| 120 |
| 121 CookieStore* store = |
| 122 url_request_context_host_.GetURLRequestContext()->cookie_store(); |
| 123 |
| 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)); |
| 129 |
| 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); |
| 134 |
| 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())); |
| 141 run_loop.Run(); |
| 142 ASSERT_TRUE(is_called); |
| 143 ASSERT_TRUE(set_cookie_result); |
| 144 |
| 145 CreateAndConnect(url, origin, cookie_header, WebSocketStandardResponse("")); |
| 146 WaitUntilConnectDone(); |
| 147 EXPECT_FALSE(has_failed()); |
| 148 } |
| 149 |
| 150 TEST_P(WebSocketStreamServerSetCookieTest, ServerSetCookie) { |
| 151 // For wss tests. |
| 152 ssl_data_.push_back(new SSLSocketDataProvider(ASYNC, OK)); |
| 153 |
| 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)); |
| 159 |
| 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" |
| 164 "%s" |
| 165 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" |
| 166 "\r\n", |
| 167 cookie_header.c_str()); |
| 168 |
| 169 CookieStore* store = |
| 170 url_request_context_host_.GetURLRequestContext()->cookie_store(); |
| 171 |
| 172 CreateAndConnect(url, origin, "", response); |
| 173 WaitUntilConnectDone(); |
| 174 EXPECT_FALSE(has_failed()); |
| 175 |
| 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())); |
| 187 run_loop.Run(); |
| 188 EXPECT_TRUE(is_called); |
| 189 EXPECT_EQ(cookie_line, get_cookies_result); |
| 190 } |
| 191 |
| 192 // Test parameters definitions follow... |
| 193 |
| 194 const ClientUseCookieParameter kClientUseCookieParameters[] = { |
| 195 // Non-secure cookies for ws |
| 196 {"ws://www.example.com", |
| 197 "http://www.example.com", |
| 198 "test-cookie", |
| 199 "Cookie: test-cookie"}, |
| 200 |
| 201 {"ws://www.example.com", |
| 202 "https://www.example.com", |
| 203 "test-cookie", |
| 204 "Cookie: test-cookie"}, |
| 205 |
| 206 {"ws://www.example.com", |
| 207 "ws://www.example.com", |
| 208 "test-cookie", |
| 209 "Cookie: test-cookie"}, |
| 210 |
| 211 {"ws://www.example.com", |
| 212 "wss://www.example.com", |
| 213 "test-cookie", |
| 214 "Cookie: test-cookie"}, |
| 215 |
| 216 // Non-secure cookies for wss |
| 217 {"wss://www.example.com", |
| 218 "http://www.example.com", |
| 219 "test-cookie", |
| 220 "Cookie: test-cookie"}, |
| 221 |
| 222 {"wss://www.example.com", |
| 223 "https://www.example.com", |
| 224 "test-cookie", |
| 225 "Cookie: test-cookie"}, |
| 226 |
| 227 {"wss://www.example.com", |
| 228 "ws://www.example.com", |
| 229 "test-cookie", |
| 230 "Cookie: test-cookie"}, |
| 231 |
| 232 {"wss://www.example.com", |
| 233 "wss://www.example.com", |
| 234 "test-cookie", |
| 235 "Cookie: test-cookie"}, |
| 236 |
| 237 // Secure-cookies for ws |
| 238 {"ws://www.example.com", |
| 239 "https://www.example.com", |
| 240 "test-cookie; secure", |
| 241 kNoCookieHeader}, |
| 242 |
| 243 {"ws://www.example.com", |
| 244 "wss://www.example.com", |
| 245 "test-cookie; secure", |
| 246 kNoCookieHeader}, |
| 247 |
| 248 // Secure-cookies for wss |
| 249 {"wss://www.example.com", |
| 250 "https://www.example.com", |
| 251 "test-cookie; secure", |
| 252 "Cookie: test-cookie"}, |
| 253 |
| 254 {"wss://www.example.com", |
| 255 "wss://www.example.com", |
| 256 "test-cookie; secure", |
| 257 "Cookie: test-cookie"}, |
| 258 |
| 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"}, |
| 264 |
| 265 {"ws://www.example.com", |
| 266 "https://www2.example.com", |
| 267 "test-cookie; Domain=example.com", |
| 268 "Cookie: test-cookie"}, |
| 269 |
| 270 {"ws://www.example.com", |
| 271 "ws://www2.example.com", |
| 272 "test-cookie; Domain=example.com", |
| 273 "Cookie: test-cookie"}, |
| 274 |
| 275 {"ws://www.example.com", |
| 276 "wss://www2.example.com", |
| 277 "test-cookie; Domain=example.com", |
| 278 "Cookie: test-cookie"}, |
| 279 |
| 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"}, |
| 285 |
| 286 {"wss://www.example.com", |
| 287 "https://www2.example.com", |
| 288 "test-cookie; Domain=example.com", |
| 289 "Cookie: test-cookie"}, |
| 290 |
| 291 {"wss://www.example.com", |
| 292 "ws://www2.example.com", |
| 293 "test-cookie; Domain=example.com", |
| 294 "Cookie: test-cookie"}, |
| 295 |
| 296 {"wss://www.example.com", |
| 297 "wss://www2.example.com", |
| 298 "test-cookie; Domain=example.com", |
| 299 "Cookie: test-cookie"}, |
| 300 |
| 301 // Secure-cookies for ws (sharing domain) |
| 302 {"ws://www.example.com", |
| 303 "https://www2.example.com", |
| 304 "test-cookie; Domain=example.com; secure", |
| 305 kNoCookieHeader}, |
| 306 |
| 307 {"ws://www.example.com", |
| 308 "wss://www2.example.com", |
| 309 "test-cookie; Domain=example.com; secure", |
| 310 kNoCookieHeader}, |
| 311 |
| 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"}, |
| 317 |
| 318 {"wss://www.example.com", |
| 319 "wss://www2.example.com", |
| 320 "test-cookie; Domain=example.com; secure", |
| 321 "Cookie: test-cookie"}, |
| 322 |
| 323 // Non-matching cookies for ws |
| 324 {"ws://www.example.com", |
| 325 "http://www2.example.com", |
| 326 "test-cookie", |
| 327 kNoCookieHeader}, |
| 328 |
| 329 {"ws://www.example.com", |
| 330 "https://www2.example.com", |
| 331 "test-cookie", |
| 332 kNoCookieHeader}, |
| 333 |
| 334 {"ws://www.example.com", |
| 335 "ws://www2.example.com", |
| 336 "test-cookie", |
| 337 kNoCookieHeader}, |
| 338 |
| 339 {"ws://www.example.com", |
| 340 "wss://www2.example.com", |
| 341 "test-cookie", |
| 342 kNoCookieHeader}, |
| 343 |
| 344 // Non-matching cookies for wss |
| 345 {"wss://www.example.com", |
| 346 "http://www2.example.com", |
| 347 "test-cookie", |
| 348 kNoCookieHeader}, |
| 349 |
| 350 {"wss://www.example.com", |
| 351 "https://www2.example.com", |
| 352 "test-cookie", |
| 353 kNoCookieHeader}, |
| 354 |
| 355 {"wss://www.example.com", |
| 356 "ws://www2.example.com", |
| 357 "test-cookie", |
| 358 kNoCookieHeader}, |
| 359 |
| 360 {"wss://www.example.com", |
| 361 "wss://www2.example.com", |
| 362 "test-cookie", |
| 363 kNoCookieHeader}, |
| 364 }; |
| 365 |
| 366 INSTANTIATE_TEST_CASE_P(WebSocketStreamClientUseCookieTest, |
| 367 WebSocketStreamClientUseCookieTest, |
| 368 ValuesIn(kClientUseCookieParameters)); |
| 369 |
| 370 const ServerSetCookieParameter kServerSetCookieParameters[] = { |
| 371 // Cookies coming from ws |
| 372 {"ws://www.example.com", |
| 373 "http://www.example.com", |
| 374 "test-cookie", |
| 375 "Set-Cookie: test-cookie"}, |
| 376 |
| 377 {"ws://www.example.com", |
| 378 "https://www.example.com", |
| 379 "test-cookie", |
| 380 "Set-Cookie: test-cookie"}, |
| 381 |
| 382 {"ws://www.example.com", |
| 383 "ws://www.example.com", |
| 384 "test-cookie", |
| 385 "Set-Cookie: test-cookie"}, |
| 386 |
| 387 {"ws://www.example.com", |
| 388 "wss://www.example.com", |
| 389 "test-cookie", |
| 390 "Set-Cookie: test-cookie"}, |
| 391 |
| 392 // Cookies coming from wss |
| 393 {"wss://www.example.com", |
| 394 "http://www.example.com", |
| 395 "test-cookie", |
| 396 "Set-Cookie: test-cookie"}, |
| 397 |
| 398 {"wss://www.example.com", |
| 399 "https://www.example.com", |
| 400 "test-cookie", |
| 401 "Set-Cookie: test-cookie"}, |
| 402 |
| 403 {"wss://www.example.com", |
| 404 "ws://www.example.com", |
| 405 "test-cookie", |
| 406 "Set-Cookie: test-cookie"}, |
| 407 |
| 408 {"wss://www.example.com", |
| 409 "wss://www.example.com", |
| 410 "test-cookie", |
| 411 "Set-Cookie: test-cookie"}, |
| 412 |
| 413 // cookies coming from ws (sharing domain) |
| 414 {"ws://www.example.com", |
| 415 "http://www2.example.com", |
| 416 "test-cookie", |
| 417 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 418 |
| 419 {"ws://www.example.com", |
| 420 "https://www2.example.com", |
| 421 "test-cookie", |
| 422 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 423 |
| 424 {"ws://www.example.com", |
| 425 "ws://www2.example.com", |
| 426 "test-cookie", |
| 427 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 428 |
| 429 {"ws://www.example.com", |
| 430 "wss://www2.example.com", |
| 431 "test-cookie", |
| 432 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 433 |
| 434 // cookies coming from wss (sharing domain) |
| 435 {"wss://www.example.com", |
| 436 "http://www2.example.com", |
| 437 "test-cookie", |
| 438 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 439 |
| 440 {"wss://www.example.com", |
| 441 "https://www2.example.com", |
| 442 "test-cookie", |
| 443 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 444 |
| 445 {"wss://www.example.com", |
| 446 "ws://www2.example.com", |
| 447 "test-cookie", |
| 448 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 449 |
| 450 {"wss://www.example.com", |
| 451 "wss://www2.example.com", |
| 452 "test-cookie", |
| 453 "Set-Cookie: test-cookie; Domain=example.com"}, |
| 454 |
| 455 // Non-matching cookies coming from ws |
| 456 {"ws://www.example.com", |
| 457 "http://www2.example.com", |
| 458 "", |
| 459 "Set-Cookie: test-cookie"}, |
| 460 |
| 461 {"ws://www.example.com", |
| 462 "https://www2.example.com", |
| 463 "", |
| 464 "Set-Cookie: test-cookie"}, |
| 465 |
| 466 {"ws://www.example.com", |
| 467 "ws://www2.example.com", |
| 468 "", |
| 469 "Set-Cookie: test-cookie"}, |
| 470 |
| 471 {"ws://www.example.com", |
| 472 "wss://www2.example.com", |
| 473 "", |
| 474 "Set-Cookie: test-cookie"}, |
| 475 |
| 476 // Non-matching cookies coming from wss |
| 477 {"wss://www.example.com", |
| 478 "http://www2.example.com", |
| 479 "", |
| 480 "Set-Cookie: test-cookie"}, |
| 481 |
| 482 {"wss://www.example.com", |
| 483 "https://www2.example.com", |
| 484 "", |
| 485 "Set-Cookie: test-cookie"}, |
| 486 |
| 487 {"wss://www.example.com", |
| 488 "ws://www2.example.com", |
| 489 "", |
| 490 "Set-Cookie: test-cookie"}, |
| 491 |
| 492 {"wss://www.example.com", |
| 493 "wss://www2.example.com", |
| 494 "", |
| 495 "Set-Cookie: test-cookie"}, |
| 496 }; |
| 497 |
| 498 INSTANTIATE_TEST_CASE_P(WebSocketStreamServerSetCookieTest, |
| 499 WebSocketStreamServerSetCookieTest, |
| 500 ValuesIn(kServerSetCookieParameters)); |
| 501 |
| 502 } // namespace |
| 503 } // namespace net |
OLD | NEW |