1 // Copyright (c) 2012 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 "net/websockets/websocket_handshake_handler.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/stringprintf.h" 13 #include "net/http/http_response_headers.h" 14 #include "net/http/http_util.h" 15 #include "url/gurl.h" 16 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 namespace { 20 21 const char* const kCookieHeaders[] = { 22 "cookie", "cookie2" 23 }; 24 25 const char* const kSetCookieHeaders[] = { 26 "set-cookie", "set-cookie2" 27 }; 28 29 // A test fixture to simplify tests for GetKeyNumber(). 30 class WebSocketHandshakeGetKeyNumberTest : public ::testing::Test { 31 protected: 32 static const char kExampleFromDraftKey1[]; 33 34 // The object is default-initialised with an empty challenge and the example 35 // key from draft-ietf-hybi-thewebsocketprotocol-00. These can be changed 36 // using set_challenge() and set_key(). 37 WebSocketHandshakeGetKeyNumberTest() 38 : challenge_(), key_(kExampleFromDraftKey1) {} 39 40 // A convenience wrapper for the function under test which automatically 41 // passes in the arguments stored in the object. 42 void GetKeyNumber() { ::net::internal::GetKeyNumber(key_, &challenge_); } 43 44 // Read current challenge. 45 const std::string& challenge() const { return challenge_; } 46 47 // Overwrite challenge. 48 void set_challenge(const std::string& challenge) { challenge_ = challenge; } 49 50 // Reset the challenge to be empty. 51 void reset_challenge() { challenge_.clear(); } 52 53 // Change key. 54 void set_key(const std::string& key) { key_ = key; } 55 56 private: 57 std::string challenge_; 58 std::string key_; 59 }; 60 61 const char WebSocketHandshakeGetKeyNumberTest::kExampleFromDraftKey1[] = 62 "3e6b263 4 17 80"; 63 64 // A version of the above fixture for death tests. 65 class WebSocketHandshakeGetKeyNumberDeathTest 66 : public WebSocketHandshakeGetKeyNumberTest { 67 }; 68 69 } // namespace 70 71 namespace net { 72 73 TEST(WebSocketHandshakeRequestHandlerTest, SimpleRequest) { 74 WebSocketHandshakeRequestHandler handler; 75 76 static const char kHandshakeRequestMessage[] = 77 "GET /demo HTTP/1.1\r\n" 78 "Host: example.com\r\n" 79 "Connection: Upgrade\r\n" 80 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" 81 "Sec-WebSocket-Protocol: sample\r\n" 82 "Upgrade: WebSocket\r\n" 83 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" 84 "Origin: http://example.com\r\n" 85 "\r\n" 86 "^n:ds[4U"; 87 88 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, 89 strlen(kHandshakeRequestMessage))); 90 EXPECT_EQ(0, handler.protocol_version()); 91 92 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); 93 94 EXPECT_EQ(kHandshakeRequestMessage, handler.GetRawRequest()); 95 } 96 97 TEST(WebSocketHandshakeRequestHandlerTest, SimpleRequestHybi06Handshake) { 98 WebSocketHandshakeRequestHandler handler; 99 100 static const char kHandshakeRequestMessage[] = 101 "GET /demo HTTP/1.1\r\n" 102 "Host: example.com\r\n" 103 "Upgrade: websocket\r\n" 104 "Connection: Upgrade\r\n" 105 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" 106 "Sec-WebSocket-Origin: http://example.com\r\n" 107 "Sec-WebSocket-Protocol: sample\r\n" 108 "Sec-WebSocket-Version: 6\r\n" 109 "\r\n"; 110 111 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, 112 strlen(kHandshakeRequestMessage))); 113 EXPECT_EQ(6, handler.protocol_version()); 114 115 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); 116 117 EXPECT_EQ(kHandshakeRequestMessage, handler.GetRawRequest()); 118 } 119 120 TEST(WebSocketHandshakeRequestHandlerTest, ReplaceRequestCookies) { 121 WebSocketHandshakeRequestHandler handler; 122 123 static const char kHandshakeRequestMessage[] = 124 "GET /demo HTTP/1.1\r\n" 125 "Host: example.com\r\n" 126 "Connection: Upgrade\r\n" 127 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" 128 "Sec-WebSocket-Protocol: sample\r\n" 129 "Upgrade: WebSocket\r\n" 130 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" 131 "Origin: http://example.com\r\n" 132 "Cookie: WK-websocket-test=1\r\n" 133 "\r\n" 134 "^n:ds[4U"; 135 136 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, 137 strlen(kHandshakeRequestMessage))); 138 EXPECT_EQ(0, handler.protocol_version()); 139 140 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); 141 142 handler.AppendHeaderIfMissing("Cookie", 143 "WK-websocket-test=1; " 144 "WK-websocket-test-httponly=1"); 145 146 static const char kHandshakeRequestExpectedMessage[] = 147 "GET /demo HTTP/1.1\r\n" 148 "Host: example.com\r\n" 149 "Connection: Upgrade\r\n" 150 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" 151 "Sec-WebSocket-Protocol: sample\r\n" 152 "Upgrade: WebSocket\r\n" 153 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" 154 "Origin: http://example.com\r\n" 155 "Cookie: WK-websocket-test=1; WK-websocket-test-httponly=1\r\n" 156 "\r\n" 157 "^n:ds[4U"; 158 159 EXPECT_EQ(kHandshakeRequestExpectedMessage, handler.GetRawRequest()); 160 } 161 162 TEST(WebSocketHandshakeRequestHandlerTest, 163 ReplaceRequestCookiesHybi06Handshake) { 164 WebSocketHandshakeRequestHandler handler; 165 166 static const char kHandshakeRequestMessage[] = 167 "GET /demo HTTP/1.1\r\n" 168 "Host: example.com\r\n" 169 "Upgrade: websocket\r\n" 170 "Connection: Upgrade\r\n" 171 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" 172 "Sec-WebSocket-Origin: http://example.com\r\n" 173 "Sec-WebSocket-Protocol: sample\r\n" 174 "Sec-WebSocket-Version: 6\r\n" 175 "Cookie: WK-websocket-test=1\r\n" 176 "\r\n"; 177 178 EXPECT_TRUE(handler.ParseRequest(kHandshakeRequestMessage, 179 strlen(kHandshakeRequestMessage))); 180 EXPECT_EQ(6, handler.protocol_version()); 181 182 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); 183 184 handler.AppendHeaderIfMissing("Cookie", 185 "WK-websocket-test=1; " 186 "WK-websocket-test-httponly=1"); 187 188 static const char kHandshakeRequestExpectedMessage[] = 189 "GET /demo HTTP/1.1\r\n" 190 "Host: example.com\r\n" 191 "Upgrade: websocket\r\n" 192 "Connection: Upgrade\r\n" 193 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" 194 "Sec-WebSocket-Origin: http://example.com\r\n" 195 "Sec-WebSocket-Protocol: sample\r\n" 196 "Sec-WebSocket-Version: 6\r\n" 197 "Cookie: WK-websocket-test=1; WK-websocket-test-httponly=1\r\n" 198 "\r\n"; 199 200 EXPECT_EQ(kHandshakeRequestExpectedMessage, handler.GetRawRequest()); 201 } 202 203 TEST(WebSocketHandshakeResponseHandlerTest, SimpleResponse) { 204 WebSocketHandshakeResponseHandler handler; 205 EXPECT_EQ(0, handler.protocol_version()); 206 207 static const char kHandshakeResponseMessage[] = 208 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 209 "Upgrade: WebSocket\r\n" 210 "Connection: Upgrade\r\n" 211 "Sec-WebSocket-Origin: http://example.com\r\n" 212 "Sec-WebSocket-Location: ws://example.com/demo\r\n" 213 "Sec-WebSocket-Protocol: sample\r\n" 214 "\r\n" 215 "8jKS'y:G*Co,Wxa-"; 216 217 EXPECT_EQ(strlen(kHandshakeResponseMessage), 218 handler.ParseRawResponse(kHandshakeResponseMessage, 219 strlen(kHandshakeResponseMessage))); 220 EXPECT_TRUE(handler.HasResponse()); 221 222 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); 223 224 EXPECT_EQ(kHandshakeResponseMessage, handler.GetResponse()); 225 } 226 227 TEST(WebSocketHandshakeResponseHandlerTest, SimpleResponseHybi06Handshake) { 228 WebSocketHandshakeResponseHandler handler; 229 handler.set_protocol_version(6); 230 EXPECT_EQ(6, handler.protocol_version()); 231 232 static const char kHandshakeResponseMessage[] = 233 "HTTP/1.1 101 Switching Protocols\r\n" 234 "Upgrade: websocket\r\n" 235 "Connection: Upgrade\r\n" 236 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 237 "Sec-WebSocket-Protocol: sample\r\n" 238 "\r\n"; 239 240 EXPECT_EQ(strlen(kHandshakeResponseMessage), 241 handler.ParseRawResponse(kHandshakeResponseMessage, 242 strlen(kHandshakeResponseMessage))); 243 EXPECT_TRUE(handler.HasResponse()); 244 245 handler.RemoveHeaders(kCookieHeaders, arraysize(kCookieHeaders)); 246 247 EXPECT_EQ(kHandshakeResponseMessage, handler.GetResponse()); 248 } 249 250 TEST(WebSocketHandshakeResponseHandlerTest, ReplaceResponseCookies) { 251 WebSocketHandshakeResponseHandler handler; 252 EXPECT_EQ(0, handler.protocol_version()); 253 254 static const char kHandshakeResponseMessage[] = 255 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 256 "Upgrade: WebSocket\r\n" 257 "Connection: Upgrade\r\n" 258 "Sec-WebSocket-Origin: http://example.com\r\n" 259 "Sec-WebSocket-Location: ws://example.com/demo\r\n" 260 "Sec-WebSocket-Protocol: sample\r\n" 261 "Set-Cookie: WK-websocket-test-1\r\n" 262 "Set-Cookie: WK-websocket-test-httponly=1; HttpOnly\r\n" 263 "\r\n" 264 "8jKS'y:G*Co,Wxa-"; 265 266 EXPECT_EQ(strlen(kHandshakeResponseMessage), 267 handler.ParseRawResponse(kHandshakeResponseMessage, 268 strlen(kHandshakeResponseMessage))); 269 EXPECT_TRUE(handler.HasResponse()); 270 std::vector<std::string> cookies; 271 handler.GetHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders), &cookies); 272 ASSERT_EQ(2U, cookies.size()); 273 EXPECT_EQ("WK-websocket-test-1", cookies[0]); 274 EXPECT_EQ("WK-websocket-test-httponly=1; HttpOnly", cookies[1]); 275 handler.RemoveHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders)); 276 277 static const char kHandshakeResponseExpectedMessage[] = 278 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 279 "Upgrade: WebSocket\r\n" 280 "Connection: Upgrade\r\n" 281 "Sec-WebSocket-Origin: http://example.com\r\n" 282 "Sec-WebSocket-Location: ws://example.com/demo\r\n" 283 "Sec-WebSocket-Protocol: sample\r\n" 284 "\r\n" 285 "8jKS'y:G*Co,Wxa-"; 286 287 EXPECT_EQ(kHandshakeResponseExpectedMessage, handler.GetResponse()); 288 } 289 290 TEST(WebSocketHandshakeResponseHandlerTest, 291 ReplaceResponseCookiesHybi06Handshake) { 292 WebSocketHandshakeResponseHandler handler; 293 handler.set_protocol_version(6); 294 EXPECT_EQ(6, handler.protocol_version()); 295 296 static const char kHandshakeResponseMessage[] = 297 "HTTP/1.1 101 Switching Protocols\r\n" 298 "Upgrade: websocket\r\n" 299 "Connection: Upgrade\r\n" 300 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 301 "Sec-WebSocket-Protocol: sample\r\n" 302 "Set-Cookie: WK-websocket-test-1\r\n" 303 "Set-Cookie: WK-websocket-test-httponly=1; HttpOnly\r\n" 304 "\r\n"; 305 306 EXPECT_EQ(strlen(kHandshakeResponseMessage), 307 handler.ParseRawResponse(kHandshakeResponseMessage, 308 strlen(kHandshakeResponseMessage))); 309 EXPECT_TRUE(handler.HasResponse()); 310 std::vector<std::string> cookies; 311 handler.GetHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders), &cookies); 312 ASSERT_EQ(2U, cookies.size()); 313 EXPECT_EQ("WK-websocket-test-1", cookies[0]); 314 EXPECT_EQ("WK-websocket-test-httponly=1; HttpOnly", cookies[1]); 315 handler.RemoveHeaders(kSetCookieHeaders, arraysize(kSetCookieHeaders)); 316 317 static const char kHandshakeResponseExpectedMessage[] = 318 "HTTP/1.1 101 Switching Protocols\r\n" 319 "Upgrade: websocket\r\n" 320 "Connection: Upgrade\r\n" 321 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 322 "Sec-WebSocket-Protocol: sample\r\n" 323 "\r\n"; 324 325 EXPECT_EQ(kHandshakeResponseExpectedMessage, handler.GetResponse()); 326 } 327 328 TEST(WebSocketHandshakeResponseHandlerTest, BadResponse) { 329 WebSocketHandshakeResponseHandler handler; 330 331 static const char kBadMessage[] = "\n\n\r\net-Location: w"; 332 EXPECT_EQ(strlen(kBadMessage), 333 handler.ParseRawResponse(kBadMessage, strlen(kBadMessage))); 334 EXPECT_TRUE(handler.HasResponse()); 335 EXPECT_EQ(kBadMessage, handler.GetResponse()); 336 } 337 338 TEST(WebSocketHandshakeResponseHandlerTest, BadResponse2) { 339 WebSocketHandshakeResponseHandler handler; 340 341 static const char kBadMessage[] = "\n\r\n\r\net-Location: w"; 342 EXPECT_EQ(strlen(kBadMessage), 343 handler.ParseRawResponse(kBadMessage, strlen(kBadMessage))); 344 EXPECT_TRUE(handler.HasResponse()); 345 EXPECT_EQ(kBadMessage, handler.GetResponse()); 346 } 347 348 TEST(WebSocketHandshakeHandlerTest, HttpRequestResponse) { 349 WebSocketHandshakeRequestHandler request_handler; 350 351 static const char kHandshakeRequestMessage[] = 352 "GET /demo HTTP/1.1\r\n" 353 "Host: example.com\r\n" 354 "Connection: Upgrade\r\n" 355 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" 356 "Sec-WebSocket-Protocol: sample\r\n" 357 "Upgrade: WebSocket\r\n" 358 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" 359 "Origin: http://example.com\r\n" 360 "\r\n" 361 "^n:ds[4U"; 362 363 EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage, 364 strlen(kHandshakeRequestMessage))); 365 EXPECT_EQ(0, request_handler.protocol_version()); 366 367 GURL url("ws://example.com/demo"); 368 std::string challenge; 369 const HttpRequestInfo& request_info = 370 request_handler.GetRequestInfo(url, &challenge); 371 372 EXPECT_EQ(url, request_info.url); 373 EXPECT_EQ("GET", request_info.method); 374 EXPECT_FALSE(request_info.extra_headers.HasHeader("Upgrade")); 375 EXPECT_FALSE(request_info.extra_headers.HasHeader("Connection")); 376 EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key1")); 377 EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key2")); 378 std::string value; 379 EXPECT_TRUE(request_info.extra_headers.GetHeader("Host", &value)); 380 EXPECT_EQ("example.com", value); 381 EXPECT_TRUE(request_info.extra_headers.GetHeader("Origin", &value)); 382 EXPECT_EQ("http://example.com", value); 383 EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Protocol", 384 &value)); 385 EXPECT_EQ("sample", value); 386 387 const char expected_challenge[] = "\x31\x6e\x41\x13\x0f\x7e\xd6\x3c^n:ds[4U"; 388 389 EXPECT_EQ(expected_challenge, challenge); 390 391 static const char kHandshakeResponseHeader[] = 392 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 393 "Sec-WebSocket-Origin: http://example.com\r\n" 394 "Sec-WebSocket-Location: ws://example.com/demo\r\n" 395 "Sec-WebSocket-Protocol: sample\r\n"; 396 397 std::string raw_headers = 398 HttpUtil::AssembleRawHeaders(kHandshakeResponseHeader, 399 strlen(kHandshakeResponseHeader)); 400 HttpResponseInfo response_info; 401 response_info.headers = new HttpResponseHeaders(raw_headers); 402 403 EXPECT_TRUE(StartsWithASCII(response_info.headers->GetStatusLine(), 404 "HTTP/1.1 101 ", false)); 405 EXPECT_FALSE(response_info.headers->HasHeader("Upgrade")); 406 EXPECT_FALSE(response_info.headers->HasHeader("Connection")); 407 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Origin", 408 "http://example.com")); 409 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Location", 410 "ws://example.com/demo")); 411 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Protocol", 412 "sample")); 413 414 WebSocketHandshakeResponseHandler response_handler; 415 EXPECT_EQ(0, response_handler.protocol_version()); 416 EXPECT_TRUE(response_handler.ParseResponseInfo(response_info, challenge)); 417 EXPECT_TRUE(response_handler.HasResponse()); 418 419 static const char kHandshakeResponseExpectedMessage[] = 420 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" 421 "Upgrade: WebSocket\r\n" 422 "Connection: Upgrade\r\n" 423 "Sec-WebSocket-Origin: http://example.com\r\n" 424 "Sec-WebSocket-Location: ws://example.com/demo\r\n" 425 "Sec-WebSocket-Protocol: sample\r\n" 426 "\r\n" 427 "8jKS'y:G*Co,Wxa-"; 428 429 EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse()); 430 } 431 432 TEST(WebSocketHandshakeHandlerTest, HttpRequestResponseHybi06Handshake) { 433 WebSocketHandshakeRequestHandler request_handler; 434 435 static const char kHandshakeRequestMessage[] = 436 "GET /demo HTTP/1.1\r\n" 437 "Host: example.com\r\n" 438 "Upgrade: websocket\r\n" 439 "Connection: Upgrade\r\n" 440 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" 441 "Sec-WebSocket-Origin: http://example.com\r\n" 442 "Sec-WebSocket-Protocol: sample\r\n" 443 "Sec-WebSocket-Version: 6\r\n" 444 "\r\n"; 445 446 EXPECT_TRUE(request_handler.ParseRequest(kHandshakeRequestMessage, 447 strlen(kHandshakeRequestMessage))); 448 EXPECT_EQ(6, request_handler.protocol_version()); 449 450 GURL url("ws://example.com/demo"); 451 std::string challenge; 452 const HttpRequestInfo& request_info = 453 request_handler.GetRequestInfo(url, &challenge); 454 455 EXPECT_EQ(url, request_info.url); 456 EXPECT_EQ("GET", request_info.method); 457 EXPECT_FALSE(request_info.extra_headers.HasHeader("Upgrade")); 458 EXPECT_FALSE(request_info.extra_headers.HasHeader("Connection")); 459 EXPECT_FALSE(request_info.extra_headers.HasHeader("Sec-WebSocket-Key")); 460 std::string value; 461 EXPECT_TRUE(request_info.extra_headers.GetHeader("Host", &value)); 462 EXPECT_EQ("example.com", value); 463 EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Origin", 464 &value)); 465 EXPECT_EQ("http://example.com", value); 466 EXPECT_TRUE(request_info.extra_headers.GetHeader("Sec-WebSocket-Protocol", 467 &value)); 468 EXPECT_EQ("sample", value); 469 470 EXPECT_EQ("dGhlIHNhbXBsZSBub25jZQ==", challenge); 471 472 static const char kHandshakeResponseHeader[] = 473 "HTTP/1.1 101 Switching Protocols\r\n" 474 "Sec-WebSocket-Protocol: sample\r\n"; 475 476 std::string raw_headers = 477 HttpUtil::AssembleRawHeaders(kHandshakeResponseHeader, 478 strlen(kHandshakeResponseHeader)); 479 HttpResponseInfo response_info; 480 response_info.headers = new HttpResponseHeaders(raw_headers); 481 482 EXPECT_TRUE(StartsWithASCII(response_info.headers->GetStatusLine(), 483 "HTTP/1.1 101 ", false)); 484 EXPECT_FALSE(response_info.headers->HasHeader("Upgrade")); 485 EXPECT_FALSE(response_info.headers->HasHeader("Connection")); 486 EXPECT_FALSE(response_info.headers->HasHeader("Sec-WebSocket-Accept")); 487 EXPECT_TRUE(response_info.headers->HasHeaderValue("Sec-WebSocket-Protocol", 488 "sample")); 489 490 WebSocketHandshakeResponseHandler response_handler; 491 response_handler.set_protocol_version(request_handler.protocol_version()); 492 EXPECT_EQ(6, response_handler.protocol_version()); 493 494 EXPECT_TRUE(response_handler.ParseResponseInfo(response_info, challenge)); 495 EXPECT_TRUE(response_handler.HasResponse()); 496 497 static const char kHandshakeResponseExpectedMessage[] = 498 "HTTP/1.1 101 Switching Protocols\r\n" 499 "Upgrade: websocket\r\n" 500 "Connection: Upgrade\r\n" 501 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" 502 "Sec-WebSocket-Protocol: sample\r\n" 503 "\r\n"; 504 505 EXPECT_EQ(kHandshakeResponseExpectedMessage, response_handler.GetResponse()); 506 } 507 508 TEST_F(WebSocketHandshakeGetKeyNumberTest, AppendsToString) { 509 set_challenge("hello"); 510 GetKeyNumber(); 511 EXPECT_EQ("hello", challenge().substr(0, 5)); 512 } 513 514 TEST_F(WebSocketHandshakeGetKeyNumberTest, AppendsFourBytes) { 515 set_challenge("hello"); 516 set_key("1 1"); 517 GetKeyNumber(); 518 EXPECT_EQ(9u, challenge().length()); 519 } 520 521 TEST_F(WebSocketHandshakeGetKeyNumberTest, IsBigEndian) { 522 set_key(base::StringPrintf("%u ", 0x61626364)); 523 GetKeyNumber(); 524 EXPECT_EQ("abcd", challenge()); 525 } 526 527 TEST_F(WebSocketHandshakeGetKeyNumberTest, IgnoresLetters) { 528 set_key("1b 1"); 529 GetKeyNumber(); 530 char expected_response[] = { 0, 0, 0, 11 }; 531 EXPECT_EQ(std::string(expected_response, 4), challenge()); 532 } 533 534 TEST_F(WebSocketHandshakeGetKeyNumberTest, DividesBySpaces) { 535 set_key("1 2"); 536 GetKeyNumber(); 537 EXPECT_EQ(12, challenge()[3]); 538 reset_challenge(); 539 set_key("1 2"); 540 GetKeyNumber(); 541 EXPECT_EQ(6, challenge()[3]); 542 reset_challenge(); 543 set_key(" 1 2"); 544 GetKeyNumber(); 545 EXPECT_EQ(4, challenge()[3]); 546 reset_challenge(); 547 set_key(" 1 2 "); 548 GetKeyNumber(); 549 EXPECT_EQ(3, challenge()[3]); 550 } 551 552 TEST_F(WebSocketHandshakeGetKeyNumberTest, MatchesExampleFromDraft) { 553 set_key("3e6b263 4 17 80"); 554 GetKeyNumber(); 555 char expected_response[] = { 0x36, 0x09, 0x65, 0x65 }; 556 EXPECT_EQ(std::string(expected_response, 4), challenge()); 557 } 558 559 TEST_F(WebSocketHandshakeGetKeyNumberTest, Maximum32bitInteger) { 560 set_key("4294967295 "); 561 GetKeyNumber(); 562 char expected_response[] = { '\xFF', '\xFF', '\xFF', '\xFF' }; 563 EXPECT_EQ(std::string(expected_response, 4), challenge()); 564 } 565 566 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) 567 TEST_F(WebSocketHandshakeGetKeyNumberDeathTest, ThirtyThreeBitIntegerNoGood) { 568 set_key(" 4294967296"); 569 EXPECT_DEBUG_DEATH(GetKeyNumber(), "overflow"); 570 } 571 572 TEST_F(WebSocketHandshakeGetKeyNumberDeathTest, NoSpacesNoGood) { 573 set_key("11"); 574 EXPECT_DEBUG_DEATH(GetKeyNumber(), "space"); 575 } 576 577 TEST_F(WebSocketHandshakeGetKeyNumberDeathTest, MustBeIntegralMultiple) { 578 set_key("1 1"); 579 EXPECT_DEBUG_DEATH(GetKeyNumber(), "spaces"); 580 } 581 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) 582 583 } // namespace net 584