1 // Copyright 2013 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_channel.h" 6 7 #include <limits.h> 8 #include <string.h> 9 10 #include <iostream> 11 #include <string> 12 #include <vector> 13 14 #include "base/bind.h" 15 #include "base/bind_helpers.h" 16 #include "base/callback.h" 17 #include "base/location.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_vector.h" 20 #include "base/memory/weak_ptr.h" 21 #include "base/message_loop/message_loop.h" 22 #include "base/strings/string_piece.h" 23 #include "net/base/net_errors.h" 24 #include "net/base/test_completion_callback.h" 25 #include "net/http/http_response_headers.h" 26 #include "net/url_request/url_request_context.h" 27 #include "net/websockets/websocket_errors.h" 28 #include "net/websockets/websocket_event_interface.h" 29 #include "net/websockets/websocket_handshake_request_info.h" 30 #include "net/websockets/websocket_handshake_response_info.h" 31 #include "net/websockets/websocket_mux.h" 32 #include "testing/gmock/include/gmock/gmock.h" 33 #include "testing/gtest/include/gtest/gtest.h" 34 #include "url/gurl.h" 35 #include "url/origin.h" 36 37 // Hacky macros to construct the body of a Close message from a code and a 38 // string, while ensuring the result is a compile-time constant string. 39 // Use like CLOSE_DATA(NORMAL_CLOSURE, "Explanation String") 40 #define CLOSE_DATA(code, string) WEBSOCKET_CLOSE_CODE_AS_STRING_##code string 41 #define WEBSOCKET_CLOSE_CODE_AS_STRING_NORMAL_CLOSURE "\x03\xe8" 42 #define WEBSOCKET_CLOSE_CODE_AS_STRING_GOING_AWAY "\x03\xe9" 43 #define WEBSOCKET_CLOSE_CODE_AS_STRING_PROTOCOL_ERROR "\x03\xea" 44 #define WEBSOCKET_CLOSE_CODE_AS_STRING_ABNORMAL_CLOSURE "\x03\xee" 45 #define WEBSOCKET_CLOSE_CODE_AS_STRING_SERVER_ERROR "\x03\xf3" 46 47 namespace net { 48 49 // Printing helpers to allow GoogleMock to print frames. These are explicitly 50 // designed to look like the static initialisation format we use in these 51 // tests. They have to live in the net namespace in order to be found by 52 // GoogleMock; a nested anonymous namespace will not work. 53 54 std::ostream& operator<<(std::ostream& os, const WebSocketFrameHeader& header) { 55 return os << (header.final ? "FINAL_FRAME" : "NOT_FINAL_FRAME") << ", " 56 << header.opcode << ", " 57 << (header.masked ? "MASKED" : "NOT_MASKED"); 58 } 59 60 std::ostream& operator<<(std::ostream& os, const WebSocketFrame& frame) { 61 os << "{" << frame.header << ", "; 62 if (frame.data.get()) { 63 return os << "\"" << base::StringPiece(frame.data->data(), 64 frame.header.payload_length) 65 << "\"}"; 66 } 67 return os << "NULL}"; 68 } 69 70 std::ostream& operator<<(std::ostream& os, 71 const ScopedVector<WebSocketFrame>& vector) { 72 os << "{"; 73 bool first = true; 74 for (ScopedVector<WebSocketFrame>::const_iterator it = vector.begin(); 75 it != vector.end(); 76 ++it) { 77 if (!first) { 78 os << ",\n"; 79 } else { 80 first = false; 81 } 82 os << **it; 83 } 84 return os << "}"; 85 } 86 87 std::ostream& operator<<(std::ostream& os, 88 const ScopedVector<WebSocketFrame>* vector) { 89 return os << '&' << *vector; 90 } 91 92 namespace { 93 94 using ::base::TimeDelta; 95 96 using ::testing::AnyNumber; 97 using ::testing::DefaultValue; 98 using ::testing::InSequence; 99 using ::testing::MockFunction; 100 using ::testing::NotNull; 101 using ::testing::Return; 102 using ::testing::SaveArg; 103 using ::testing::StrictMock; 104 using ::testing::_; 105 106 // A selection of characters that have traditionally been mangled in some 107 // environment or other, for testing 8-bit cleanliness. 108 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL 109 '\0', // nul 110 '\x7F', // DEL 111 '\x80', '\xFF', // NOT VALID UTF-8 112 '\x1A', // Control-Z, EOF on DOS 113 '\x03', // Control-C 114 '\x04', // EOT, special for Unix terms 115 '\x1B', // ESC, often special 116 '\b', // backspace 117 '\'', // single-quote, special in PHP 118 }; 119 const size_t kBinaryBlobSize = arraysize(kBinaryBlob); 120 121 // The amount of quota a new connection gets by default. 122 // TODO(ricea): If kDefaultSendQuotaHighWaterMark changes, then this value will 123 // need to be updated. 124 const size_t kDefaultInitialQuota = 1 << 17; 125 // The amount of bytes we need to send after the initial connection to trigger a 126 // quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or 127 // kDefaultSendQuotaLowWaterMark change. 128 const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1; 129 130 // TestTimeouts::tiny_timeout() is 100ms! I could run halfway around the world 131 // in that time! I would like my tests to run a bit quicker. 132 const int kVeryTinyTimeoutMillis = 1; 133 134 // Enough quota to pass any test. 135 const int64 kPlentyOfQuota = INT_MAX; 136 137 typedef WebSocketEventInterface::ChannelState ChannelState; 138 const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE; 139 const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED; 140 141 // This typedef mainly exists to avoid having to repeat the "NOLINT" incantation 142 // all over the place. 143 typedef StrictMock< MockFunction<void(int)> > Checkpoint; // NOLINT 144 145 // This mock is for testing expectations about how the EventInterface is used. 146 class MockWebSocketEventInterface : public WebSocketEventInterface { 147 public: 148 MockWebSocketEventInterface() {} 149 150 MOCK_METHOD3(OnAddChannelResponse, 151 ChannelState(bool, 152 const std::string&, 153 const std::string&)); // NOLINT 154 MOCK_METHOD3(OnDataFrame, 155 ChannelState(bool, 156 WebSocketMessageType, 157 const std::vector<char>&)); // NOLINT 158 MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT 159 MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT 160 MOCK_METHOD1(OnFailChannel, ChannelState(const std::string&)); // NOLINT 161 MOCK_METHOD3(OnDropChannel, 162 ChannelState(bool, uint16, const std::string&)); // NOLINT 163 164 // We can't use GMock with scoped_ptr. 165 ChannelState OnStartOpeningHandshake( 166 scoped_ptr<WebSocketHandshakeRequestInfo>) OVERRIDE { 167 OnStartOpeningHandshakeCalled(); 168 return CHANNEL_ALIVE; 169 } 170 ChannelState OnFinishOpeningHandshake( 171 scoped_ptr<WebSocketHandshakeResponseInfo>) OVERRIDE { 172 OnFinishOpeningHandshakeCalled(); 173 return CHANNEL_ALIVE; 174 } 175 virtual ChannelState OnSSLCertificateError( 176 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks, 177 const GURL& url, 178 const SSLInfo& ssl_info, 179 bool fatal) OVERRIDE { 180 OnSSLCertificateErrorCalled( 181 ssl_error_callbacks.get(), url, ssl_info, fatal); 182 return CHANNEL_ALIVE; 183 } 184 185 MOCK_METHOD0(OnStartOpeningHandshakeCalled, void()); // NOLINT 186 MOCK_METHOD0(OnFinishOpeningHandshakeCalled, void()); // NOLINT 187 MOCK_METHOD4( 188 OnSSLCertificateErrorCalled, 189 void(SSLErrorCallbacks*, const GURL&, const SSLInfo&, bool)); // NOLINT 190 }; 191 192 // This fake EventInterface is for tests which need a WebSocketEventInterface 193 // implementation but are not verifying how it is used. 194 class FakeWebSocketEventInterface : public WebSocketEventInterface { 195 virtual ChannelState OnAddChannelResponse( 196 bool fail, 197 const std::string& selected_protocol, 198 const std::string& extensions) OVERRIDE { 199 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; 200 } 201 virtual ChannelState OnDataFrame(bool fin, 202 WebSocketMessageType type, 203 const std::vector<char>& data) OVERRIDE { 204 return CHANNEL_ALIVE; 205 } 206 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { 207 return CHANNEL_ALIVE; 208 } 209 virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; } 210 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE { 211 return CHANNEL_DELETED; 212 } 213 virtual ChannelState OnDropChannel(bool was_clean, 214 uint16 code, 215 const std::string& reason) OVERRIDE { 216 return CHANNEL_DELETED; 217 } 218 virtual ChannelState OnStartOpeningHandshake( 219 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { 220 return CHANNEL_ALIVE; 221 } 222 virtual ChannelState OnFinishOpeningHandshake( 223 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { 224 return CHANNEL_ALIVE; 225 } 226 virtual ChannelState OnSSLCertificateError( 227 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks, 228 const GURL& url, 229 const SSLInfo& ssl_info, 230 bool fatal) OVERRIDE { 231 return CHANNEL_ALIVE; 232 } 233 }; 234 235 // This fake WebSocketStream is for tests that require a WebSocketStream but are 236 // not testing the way it is used. It has minimal functionality to return 237 // the |protocol| and |extensions| that it was constructed with. 238 class FakeWebSocketStream : public WebSocketStream { 239 public: 240 // Constructs with empty protocol and extensions. 241 FakeWebSocketStream() {} 242 243 // Constructs with specified protocol and extensions. 244 FakeWebSocketStream(const std::string& protocol, 245 const std::string& extensions) 246 : protocol_(protocol), extensions_(extensions) {} 247 248 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 249 const CompletionCallback& callback) OVERRIDE { 250 return ERR_IO_PENDING; 251 } 252 253 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 254 const CompletionCallback& callback) OVERRIDE { 255 return ERR_IO_PENDING; 256 } 257 258 virtual void Close() OVERRIDE {} 259 260 // Returns the string passed to the constructor. 261 virtual std::string GetSubProtocol() const OVERRIDE { return protocol_; } 262 263 // Returns the string passed to the constructor. 264 virtual std::string GetExtensions() const OVERRIDE { return extensions_; } 265 266 private: 267 // The string to return from GetSubProtocol(). 268 std::string protocol_; 269 270 // The string to return from GetExtensions(). 271 std::string extensions_; 272 }; 273 274 // To make the static initialisers easier to read, we use enums rather than 275 // bools. 276 enum IsFinal { NOT_FINAL_FRAME, FINAL_FRAME }; 277 278 enum IsMasked { NOT_MASKED, MASKED }; 279 280 // This is used to initialise a WebSocketFrame but is statically initialisable. 281 struct InitFrame { 282 IsFinal final; 283 // Reserved fields omitted for now. Add them if you need them. 284 WebSocketFrameHeader::OpCode opcode; 285 IsMasked masked; 286 287 // Will be used to create the IOBuffer member. Can be NULL for NULL data. Is a 288 // nul-terminated string for ease-of-use. |header.payload_length| is 289 // initialised from |strlen(data)|. This means it is not 8-bit clean, but this 290 // is not an issue for test data. 291 const char* const data; 292 }; 293 294 // For GoogleMock 295 std::ostream& operator<<(std::ostream& os, const InitFrame& frame) { 296 os << "{" << (frame.final == FINAL_FRAME ? "FINAL_FRAME" : "NOT_FINAL_FRAME") 297 << ", " << frame.opcode << ", " 298 << (frame.masked == MASKED ? "MASKED" : "NOT_MASKED") << ", "; 299 if (frame.data) { 300 return os << "\"" << frame.data << "\"}"; 301 } 302 return os << "NULL}"; 303 } 304 305 template <size_t N> 306 std::ostream& operator<<(std::ostream& os, const InitFrame (&frames)[N]) { 307 os << "{"; 308 bool first = true; 309 for (size_t i = 0; i < N; ++i) { 310 if (!first) { 311 os << ",\n"; 312 } else { 313 first = false; 314 } 315 os << frames[i]; 316 } 317 return os << "}"; 318 } 319 320 // Convert a const array of InitFrame structs to the format used at 321 // runtime. Templated on the size of the array to save typing. 322 template <size_t N> 323 ScopedVector<WebSocketFrame> CreateFrameVector( 324 const InitFrame (&source_frames)[N]) { 325 ScopedVector<WebSocketFrame> result_frames; 326 result_frames.reserve(N); 327 for (size_t i = 0; i < N; ++i) { 328 const InitFrame& source_frame = source_frames[i]; 329 scoped_ptr<WebSocketFrame> result_frame( 330 new WebSocketFrame(source_frame.opcode)); 331 size_t frame_length = source_frame.data ? strlen(source_frame.data) : 0; 332 WebSocketFrameHeader& result_header = result_frame->header; 333 result_header.final = (source_frame.final == FINAL_FRAME); 334 result_header.masked = (source_frame.masked == MASKED); 335 result_header.payload_length = frame_length; 336 if (source_frame.data) { 337 result_frame->data = new IOBuffer(frame_length); 338 memcpy(result_frame->data->data(), source_frame.data, frame_length); 339 } 340 result_frames.push_back(result_frame.release()); 341 } 342 return result_frames.Pass(); 343 } 344 345 // A GoogleMock action which can be used to respond to call to ReadFrames with 346 // some frames. Use like ReadFrames(_, _).WillOnce(ReturnFrames(&frames)); 347 // |frames| is an array of InitFrame. |frames| needs to be passed by pointer 348 // because otherwise it will be treated as a pointer and the array size 349 // information will be lost. 350 ACTION_P(ReturnFrames, source_frames) { 351 *arg0 = CreateFrameVector(*source_frames); 352 return OK; 353 } 354 355 // The implementation of a GoogleMock matcher which can be used to compare a 356 // ScopedVector<WebSocketFrame>* against an expectation defined as an array of 357 // InitFrame objects. Although it is possible to compose built-in GoogleMock 358 // matchers to check the contents of a WebSocketFrame, the results are so 359 // unreadable that it is better to use this matcher. 360 template <size_t N> 361 class EqualsFramesMatcher 362 : public ::testing::MatcherInterface<ScopedVector<WebSocketFrame>*> { 363 public: 364 EqualsFramesMatcher(const InitFrame (*expect_frames)[N]) 365 : expect_frames_(expect_frames) {} 366 367 virtual bool MatchAndExplain(ScopedVector<WebSocketFrame>* actual_frames, 368 ::testing::MatchResultListener* listener) const { 369 if (actual_frames->size() != N) { 370 *listener << "the vector size is " << actual_frames->size(); 371 return false; 372 } 373 for (size_t i = 0; i < N; ++i) { 374 const WebSocketFrame& actual_frame = *(*actual_frames)[i]; 375 const InitFrame& expected_frame = (*expect_frames_)[i]; 376 if (actual_frame.header.final != (expected_frame.final == FINAL_FRAME)) { 377 *listener << "the frame is marked as " 378 << (actual_frame.header.final ? "" : "not ") << "final"; 379 return false; 380 } 381 if (actual_frame.header.opcode != expected_frame.opcode) { 382 *listener << "the opcode is " << actual_frame.header.opcode; 383 return false; 384 } 385 if (actual_frame.header.masked != (expected_frame.masked == MASKED)) { 386 *listener << "the frame is " 387 << (actual_frame.header.masked ? "masked" : "not masked"); 388 return false; 389 } 390 const size_t expected_length = 391 expected_frame.data ? strlen(expected_frame.data) : 0; 392 if (actual_frame.header.payload_length != expected_length) { 393 *listener << "the payload length is " 394 << actual_frame.header.payload_length; 395 return false; 396 } 397 if (expected_length != 0 && 398 memcmp(actual_frame.data->data(), 399 expected_frame.data, 400 actual_frame.header.payload_length) != 0) { 401 *listener << "the data content differs"; 402 return false; 403 } 404 } 405 return true; 406 } 407 408 virtual void DescribeTo(std::ostream* os) const { 409 *os << "matches " << *expect_frames_; 410 } 411 412 virtual void DescribeNegationTo(std::ostream* os) const { 413 *os << "does not match " << *expect_frames_; 414 } 415 416 private: 417 const InitFrame (*expect_frames_)[N]; 418 }; 419 420 // The definition of EqualsFrames GoogleMock matcher. Unlike the ReturnFrames 421 // action, this can take the array by reference. 422 template <size_t N> 423 ::testing::Matcher<ScopedVector<WebSocketFrame>*> EqualsFrames( 424 const InitFrame (&frames)[N]) { 425 return ::testing::MakeMatcher(new EqualsFramesMatcher<N>(&frames)); 426 } 427 428 // TestClosure works like TestCompletionCallback, but doesn't take an argument. 429 class TestClosure { 430 public: 431 base::Closure closure() { return base::Bind(callback_.callback(), OK); } 432 433 void WaitForResult() { callback_.WaitForResult(); } 434 435 private: 436 // Delegate to TestCompletionCallback for the implementation. 437 TestCompletionCallback callback_; 438 }; 439 440 // A GoogleMock action to run a Closure. 441 ACTION_P(InvokeClosure, closure) { closure.Run(); } 442 443 // A GoogleMock action to run a Closure and return CHANNEL_DELETED. 444 ACTION_P(InvokeClosureReturnDeleted, closure) { 445 closure.Run(); 446 return WebSocketEventInterface::CHANNEL_DELETED; 447 } 448 449 // A FakeWebSocketStream whose ReadFrames() function returns data. 450 class ReadableFakeWebSocketStream : public FakeWebSocketStream { 451 public: 452 enum IsSync { SYNC, ASYNC }; 453 454 // After constructing the object, call PrepareReadFrames() once for each 455 // time you wish it to return from the test. 456 ReadableFakeWebSocketStream() : index_(0), read_frames_pending_(false) {} 457 458 // Check that all the prepared responses have been consumed. 459 virtual ~ReadableFakeWebSocketStream() { 460 CHECK(index_ >= responses_.size()); 461 CHECK(!read_frames_pending_); 462 } 463 464 // Prepares a fake response. Fake responses will be returned from ReadFrames() 465 // in the same order they were prepared with PrepareReadFrames() and 466 // PrepareReadFramesError(). If |async| is ASYNC, then ReadFrames() will 467 // return ERR_IO_PENDING and the callback will be scheduled to run on the 468 // message loop. This requires the test case to run the message loop. If 469 // |async| is SYNC, the response will be returned synchronously. |error| is 470 // returned directly from ReadFrames() in the synchronous case, or passed to 471 // the callback in the asynchronous case. |frames| will be converted to a 472 // ScopedVector<WebSocketFrame> and copied to the pointer that was passed to 473 // ReadFrames(). 474 template <size_t N> 475 void PrepareReadFrames(IsSync async, 476 int error, 477 const InitFrame (&frames)[N]) { 478 responses_.push_back(new Response(async, error, CreateFrameVector(frames))); 479 } 480 481 // An alternate version of PrepareReadFrames for when we need to construct 482 // the frames manually. 483 void PrepareRawReadFrames(IsSync async, 484 int error, 485 ScopedVector<WebSocketFrame> frames) { 486 responses_.push_back(new Response(async, error, frames.Pass())); 487 } 488 489 // Prepares a fake error response (ie. there is no data). 490 void PrepareReadFramesError(IsSync async, int error) { 491 responses_.push_back( 492 new Response(async, error, ScopedVector<WebSocketFrame>())); 493 } 494 495 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 496 const CompletionCallback& callback) OVERRIDE { 497 CHECK(!read_frames_pending_); 498 if (index_ >= responses_.size()) 499 return ERR_IO_PENDING; 500 if (responses_[index_]->async == ASYNC) { 501 read_frames_pending_ = true; 502 base::MessageLoop::current()->PostTask( 503 FROM_HERE, 504 base::Bind(&ReadableFakeWebSocketStream::DoCallback, 505 base::Unretained(this), 506 frames, 507 callback)); 508 return ERR_IO_PENDING; 509 } else { 510 frames->swap(responses_[index_]->frames); 511 return responses_[index_++]->error; 512 } 513 } 514 515 private: 516 void DoCallback(ScopedVector<WebSocketFrame>* frames, 517 const CompletionCallback& callback) { 518 read_frames_pending_ = false; 519 frames->swap(responses_[index_]->frames); 520 callback.Run(responses_[index_++]->error); 521 return; 522 } 523 524 struct Response { 525 Response(IsSync async, int error, ScopedVector<WebSocketFrame> frames) 526 : async(async), error(error), frames(frames.Pass()) {} 527 528 IsSync async; 529 int error; 530 ScopedVector<WebSocketFrame> frames; 531 532 private: 533 // Bad things will happen if we attempt to copy or assign |frames|. 534 DISALLOW_COPY_AND_ASSIGN(Response); 535 }; 536 ScopedVector<Response> responses_; 537 538 // The index into the responses_ array of the next response to be returned. 539 size_t index_; 540 541 // True when an async response from ReadFrames() is pending. This only applies 542 // to "real" async responses. Once all the prepared responses have been 543 // returned, ReadFrames() returns ERR_IO_PENDING but read_frames_pending_ is 544 // not set to true. 545 bool read_frames_pending_; 546 }; 547 548 // A FakeWebSocketStream where writes always complete successfully and 549 // synchronously. 550 class WriteableFakeWebSocketStream : public FakeWebSocketStream { 551 public: 552 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 553 const CompletionCallback& callback) OVERRIDE { 554 return OK; 555 } 556 }; 557 558 // A FakeWebSocketStream where writes always fail. 559 class UnWriteableFakeWebSocketStream : public FakeWebSocketStream { 560 public: 561 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 562 const CompletionCallback& callback) OVERRIDE { 563 return ERR_CONNECTION_RESET; 564 } 565 }; 566 567 // A FakeWebSocketStream which echoes any frames written back. Clears the 568 // "masked" header bit, but makes no other checks for validity. Tests using this 569 // must run the MessageLoop to receive the callback(s). If a message with opcode 570 // Close is echoed, then an ERR_CONNECTION_CLOSED is returned in the next 571 // callback. The test must do something to cause WriteFrames() to be called, 572 // otherwise the ReadFrames() callback will never be called. 573 class EchoeyFakeWebSocketStream : public FakeWebSocketStream { 574 public: 575 EchoeyFakeWebSocketStream() : read_frames_(NULL), done_(false) {} 576 577 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 578 const CompletionCallback& callback) OVERRIDE { 579 // Users of WebSocketStream will not expect the ReadFrames() callback to be 580 // called from within WriteFrames(), so post it to the message loop instead. 581 stored_frames_.insert(stored_frames_.end(), frames->begin(), frames->end()); 582 frames->weak_clear(); 583 PostCallback(); 584 return OK; 585 } 586 587 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 588 const CompletionCallback& callback) OVERRIDE { 589 read_callback_ = callback; 590 read_frames_ = frames; 591 if (done_) 592 PostCallback(); 593 return ERR_IO_PENDING; 594 } 595 596 private: 597 void PostCallback() { 598 base::MessageLoop::current()->PostTask( 599 FROM_HERE, 600 base::Bind(&EchoeyFakeWebSocketStream::DoCallback, 601 base::Unretained(this))); 602 } 603 604 void DoCallback() { 605 if (done_) { 606 read_callback_.Run(ERR_CONNECTION_CLOSED); 607 } else if (!stored_frames_.empty()) { 608 done_ = MoveFrames(read_frames_); 609 read_frames_ = NULL; 610 read_callback_.Run(OK); 611 } 612 } 613 614 // Copy the frames stored in stored_frames_ to |out|, while clearing the 615 // "masked" header bit. Returns true if a Close Frame was seen, false 616 // otherwise. 617 bool MoveFrames(ScopedVector<WebSocketFrame>* out) { 618 bool seen_close = false; 619 *out = stored_frames_.Pass(); 620 for (ScopedVector<WebSocketFrame>::iterator it = out->begin(); 621 it != out->end(); 622 ++it) { 623 WebSocketFrameHeader& header = (*it)->header; 624 header.masked = false; 625 if (header.opcode == WebSocketFrameHeader::kOpCodeClose) 626 seen_close = true; 627 } 628 return seen_close; 629 } 630 631 ScopedVector<WebSocketFrame> stored_frames_; 632 CompletionCallback read_callback_; 633 // Owned by the caller of ReadFrames(). 634 ScopedVector<WebSocketFrame>* read_frames_; 635 // True if we should close the connection. 636 bool done_; 637 }; 638 639 // A FakeWebSocketStream where writes trigger a connection reset. 640 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous 641 // and triggers ReadFrames to return a reset as well. Tests using this need to 642 // run the message loop. There are two tricky parts here: 643 // 1. Calling the write callback may call Close(), after which the read callback 644 // should not be called. 645 // 2. Calling either callback may delete the stream altogether. 646 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { 647 public: 648 ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {} 649 650 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 651 const CompletionCallback& callback) OVERRIDE { 652 base::MessageLoop::current()->PostTask( 653 FROM_HERE, 654 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, 655 weak_ptr_factory_.GetWeakPtr(), 656 callback, 657 ERR_CONNECTION_RESET)); 658 base::MessageLoop::current()->PostTask( 659 FROM_HERE, 660 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, 661 weak_ptr_factory_.GetWeakPtr(), 662 read_callback_, 663 ERR_CONNECTION_RESET)); 664 return ERR_IO_PENDING; 665 } 666 667 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 668 const CompletionCallback& callback) OVERRIDE { 669 read_callback_ = callback; 670 return ERR_IO_PENDING; 671 } 672 673 virtual void Close() OVERRIDE { closed_ = true; } 674 675 private: 676 void CallCallbackUnlessClosed(const CompletionCallback& callback, int value) { 677 if (!closed_) 678 callback.Run(value); 679 } 680 681 CompletionCallback read_callback_; 682 bool closed_; 683 // An IO error can result in the socket being deleted, so we use weak pointers 684 // to ensure correct behaviour in that case. 685 base::WeakPtrFactory<ResetOnWriteFakeWebSocketStream> weak_ptr_factory_; 686 }; 687 688 // This mock is for verifying that WebSocket protocol semantics are obeyed (to 689 // the extent that they are implemented in WebSocketCommon). 690 class MockWebSocketStream : public WebSocketStream { 691 public: 692 MOCK_METHOD2(ReadFrames, 693 int(ScopedVector<WebSocketFrame>* frames, 694 const CompletionCallback& callback)); 695 MOCK_METHOD2(WriteFrames, 696 int(ScopedVector<WebSocketFrame>* frames, 697 const CompletionCallback& callback)); 698 MOCK_METHOD0(Close, void()); 699 MOCK_CONST_METHOD0(GetSubProtocol, std::string()); 700 MOCK_CONST_METHOD0(GetExtensions, std::string()); 701 MOCK_METHOD0(AsWebSocketStream, WebSocketStream*()); 702 }; 703 704 struct ArgumentCopyingWebSocketStreamCreator { 705 scoped_ptr<WebSocketStreamRequest> Create( 706 const GURL& socket_url, 707 const std::vector<std::string>& requested_subprotocols, 708 const url::Origin& origin, 709 URLRequestContext* url_request_context, 710 const BoundNetLog& net_log, 711 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate) { 712 this->socket_url = socket_url; 713 this->requested_subprotocols = requested_subprotocols; 714 this->origin = origin; 715 this->url_request_context = url_request_context; 716 this->net_log = net_log; 717 this->connect_delegate = connect_delegate.Pass(); 718 return make_scoped_ptr(new WebSocketStreamRequest); 719 } 720 721 GURL socket_url; 722 url::Origin origin; 723 std::vector<std::string> requested_subprotocols; 724 URLRequestContext* url_request_context; 725 BoundNetLog net_log; 726 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate; 727 }; 728 729 // Converts a std::string to a std::vector<char>. For test purposes, it is 730 // convenient to be able to specify data as a string, but the 731 // WebSocketEventInterface requires the vector<char> type. 732 std::vector<char> AsVector(const std::string& s) { 733 return std::vector<char>(s.begin(), s.end()); 734 } 735 736 class FakeSSLErrorCallbacks 737 : public WebSocketEventInterface::SSLErrorCallbacks { 738 public: 739 virtual void CancelSSLRequest(int error, const SSLInfo* ssl_info) OVERRIDE {} 740 virtual void ContinueSSLRequest() OVERRIDE {} 741 }; 742 743 // Base class for all test fixtures. 744 class WebSocketChannelTest : public ::testing::Test { 745 protected: 746 WebSocketChannelTest() : stream_(new FakeWebSocketStream) {} 747 748 // Creates a new WebSocketChannel and connects it, using the settings stored 749 // in |connect_data_|. 750 void CreateChannelAndConnect() { 751 channel_.reset(new WebSocketChannel(CreateEventInterface(), 752 &connect_data_.url_request_context)); 753 channel_->SendAddChannelRequestForTesting( 754 connect_data_.socket_url, 755 connect_data_.requested_subprotocols, 756 connect_data_.origin, 757 base::Bind(&ArgumentCopyingWebSocketStreamCreator::Create, 758 base::Unretained(&connect_data_.creator))); 759 } 760 761 // Same as CreateChannelAndConnect(), but calls the on_success callback as 762 // well. This method is virtual so that subclasses can also set the stream. 763 virtual void CreateChannelAndConnectSuccessfully() { 764 CreateChannelAndConnect(); 765 // Most tests aren't concerned with flow control from the renderer, so allow 766 // MAX_INT quota units. 767 channel_->SendFlowControl(kPlentyOfQuota); 768 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 769 } 770 771 // Returns a WebSocketEventInterface to be passed to the WebSocketChannel. 772 // This implementation returns a newly-created fake. Subclasses may return a 773 // mock instead. 774 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() { 775 return scoped_ptr<WebSocketEventInterface>(new FakeWebSocketEventInterface); 776 } 777 778 // This method serves no other purpose than to provide a nice syntax for 779 // assigning to stream_. class T must be a subclass of WebSocketStream or you 780 // will have unpleasant compile errors. 781 template <class T> 782 void set_stream(scoped_ptr<T> stream) { 783 // Since the definition of "PassAs" depends on the type T, the C++ standard 784 // requires the "template" keyword to indicate that "PassAs" should be 785 // parsed as a template method. 786 stream_ = stream.template PassAs<WebSocketStream>(); 787 } 788 789 // A struct containing the data that will be used to connect the channel. 790 // Grouped for readability. 791 struct ConnectData { 792 ConnectData() : socket_url("ws://ws/"), origin("http://ws") {} 793 794 // URLRequestContext object. 795 URLRequestContext url_request_context; 796 797 // URL to (pretend to) connect to. 798 GURL socket_url; 799 // Requested protocols for the request. 800 std::vector<std::string> requested_subprotocols; 801 // Origin of the request 802 url::Origin origin; 803 804 // A fake WebSocketStreamCreator that just records its arguments. 805 ArgumentCopyingWebSocketStreamCreator creator; 806 }; 807 ConnectData connect_data_; 808 809 // The channel we are testing. Not initialised until SetChannel() is called. 810 scoped_ptr<WebSocketChannel> channel_; 811 812 // A mock or fake stream for tests that need one. 813 scoped_ptr<WebSocketStream> stream_; 814 }; 815 816 // enum of WebSocketEventInterface calls. These are intended to be or'd together 817 // in order to instruct WebSocketChannelDeletingTest when it should fail. 818 enum EventInterfaceCall { 819 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, 820 EVENT_ON_DATA_FRAME = 0x2, 821 EVENT_ON_FLOW_CONTROL = 0x4, 822 EVENT_ON_CLOSING_HANDSHAKE = 0x8, 823 EVENT_ON_FAIL_CHANNEL = 0x10, 824 EVENT_ON_DROP_CHANNEL = 0x20, 825 EVENT_ON_START_OPENING_HANDSHAKE = 0x40, 826 EVENT_ON_FINISH_OPENING_HANDSHAKE = 0x80, 827 EVENT_ON_SSL_CERTIFICATE_ERROR = 0x100, 828 }; 829 830 class WebSocketChannelDeletingTest : public WebSocketChannelTest { 831 public: 832 ChannelState DeleteIfDeleting(EventInterfaceCall call) { 833 if (deleting_ & call) { 834 channel_.reset(); 835 return CHANNEL_DELETED; 836 } else { 837 return CHANNEL_ALIVE; 838 } 839 } 840 841 protected: 842 WebSocketChannelDeletingTest() 843 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | 844 EVENT_ON_FLOW_CONTROL | 845 EVENT_ON_CLOSING_HANDSHAKE | 846 EVENT_ON_FAIL_CHANNEL | 847 EVENT_ON_DROP_CHANNEL | 848 EVENT_ON_START_OPENING_HANDSHAKE | 849 EVENT_ON_FINISH_OPENING_HANDSHAKE | 850 EVENT_ON_SSL_CERTIFICATE_ERROR) {} 851 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to 852 // avoid circular dependency. 853 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; 854 855 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they 856 // want to cause Channel deletion. The default is for all calls to cause 857 // deletion. 858 int deleting_; 859 }; 860 861 // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to 862 // connect. 863 class ChannelDeletingFakeWebSocketEventInterface 864 : public FakeWebSocketEventInterface { 865 public: 866 ChannelDeletingFakeWebSocketEventInterface( 867 WebSocketChannelDeletingTest* fixture) 868 : fixture_(fixture) {} 869 870 virtual ChannelState OnAddChannelResponse( 871 bool fail, 872 const std::string& selected_protocol, 873 const std::string& extensions) OVERRIDE { 874 return fixture_->DeleteIfDeleting(EVENT_ON_ADD_CHANNEL_RESPONSE); 875 } 876 877 virtual ChannelState OnDataFrame(bool fin, 878 WebSocketMessageType type, 879 const std::vector<char>& data) OVERRIDE { 880 return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME); 881 } 882 883 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { 884 return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL); 885 } 886 887 virtual ChannelState OnClosingHandshake() OVERRIDE { 888 return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE); 889 } 890 891 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE { 892 return fixture_->DeleteIfDeleting(EVENT_ON_FAIL_CHANNEL); 893 } 894 895 virtual ChannelState OnDropChannel(bool was_clean, 896 uint16 code, 897 const std::string& reason) OVERRIDE { 898 return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL); 899 } 900 901 virtual ChannelState OnStartOpeningHandshake( 902 scoped_ptr<WebSocketHandshakeRequestInfo> request) OVERRIDE { 903 return fixture_->DeleteIfDeleting(EVENT_ON_START_OPENING_HANDSHAKE); 904 } 905 virtual ChannelState OnFinishOpeningHandshake( 906 scoped_ptr<WebSocketHandshakeResponseInfo> response) OVERRIDE { 907 return fixture_->DeleteIfDeleting(EVENT_ON_FINISH_OPENING_HANDSHAKE); 908 } 909 virtual ChannelState OnSSLCertificateError( 910 scoped_ptr<SSLErrorCallbacks> ssl_error_callbacks, 911 const GURL& url, 912 const SSLInfo& ssl_info, 913 bool fatal) OVERRIDE { 914 return fixture_->DeleteIfDeleting(EVENT_ON_SSL_CERTIFICATE_ERROR); 915 } 916 917 private: 918 // A pointer to the test fixture. Owned by the test harness; this object will 919 // be deleted before it is. 920 WebSocketChannelDeletingTest* fixture_; 921 }; 922 923 scoped_ptr<WebSocketEventInterface> 924 WebSocketChannelDeletingTest::CreateEventInterface() { 925 return scoped_ptr<WebSocketEventInterface>( 926 new ChannelDeletingFakeWebSocketEventInterface(this)); 927 } 928 929 // Base class for tests which verify that EventInterface methods are called 930 // appropriately. 931 class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest { 932 protected: 933 WebSocketChannelEventInterfaceTest() 934 : event_interface_(new StrictMock<MockWebSocketEventInterface>) { 935 DefaultValue<ChannelState>::Set(CHANNEL_ALIVE); 936 ON_CALL(*event_interface_, OnAddChannelResponse(true, _, _)) 937 .WillByDefault(Return(CHANNEL_DELETED)); 938 ON_CALL(*event_interface_, OnDropChannel(_, _, _)) 939 .WillByDefault(Return(CHANNEL_DELETED)); 940 ON_CALL(*event_interface_, OnFailChannel(_)) 941 .WillByDefault(Return(CHANNEL_DELETED)); 942 } 943 944 virtual ~WebSocketChannelEventInterfaceTest() { 945 DefaultValue<ChannelState>::Clear(); 946 } 947 948 // Tests using this fixture must set expectations on the event_interface_ mock 949 // object before calling CreateChannelAndConnect() or 950 // CreateChannelAndConnectSuccessfully(). This will only work once per test 951 // case, but once should be enough. 952 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE { 953 return scoped_ptr<WebSocketEventInterface>(event_interface_.release()); 954 } 955 956 scoped_ptr<MockWebSocketEventInterface> event_interface_; 957 }; 958 959 // Base class for tests which verify that WebSocketStream methods are called 960 // appropriately by using a MockWebSocketStream. 961 class WebSocketChannelStreamTest : public WebSocketChannelTest { 962 protected: 963 WebSocketChannelStreamTest() 964 : mock_stream_(new StrictMock<MockWebSocketStream>) {} 965 966 virtual void CreateChannelAndConnectSuccessfully() OVERRIDE { 967 set_stream(mock_stream_.Pass()); 968 WebSocketChannelTest::CreateChannelAndConnectSuccessfully(); 969 } 970 971 scoped_ptr<MockWebSocketStream> mock_stream_; 972 }; 973 974 // Fixture for tests which test UTF-8 validation of sent Text frames via the 975 // EventInterface. 976 class WebSocketChannelSendUtf8Test 977 : public WebSocketChannelEventInterfaceTest { 978 public: 979 virtual void SetUp() { 980 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 981 // For the purpose of the tests using this fixture, it doesn't matter 982 // whether these methods are called or not. 983 EXPECT_CALL(*event_interface_, OnAddChannelResponse(_, _, _)) 984 .Times(AnyNumber()); 985 EXPECT_CALL(*event_interface_, OnFlowControl(_)) 986 .Times(AnyNumber()); 987 } 988 }; 989 990 // Fixture for tests which test use of receive quota from the renderer. 991 class WebSocketChannelFlowControlTest 992 : public WebSocketChannelEventInterfaceTest { 993 protected: 994 // Tests using this fixture should use CreateChannelAndConnectWithQuota() 995 // instead of CreateChannelAndConnectSuccessfully(). 996 void CreateChannelAndConnectWithQuota(int64 quota) { 997 CreateChannelAndConnect(); 998 channel_->SendFlowControl(quota); 999 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 1000 } 1001 1002 virtual void CreateChannelAndConnectSuccesfully() { NOTREACHED(); } 1003 }; 1004 1005 // Fixture for tests which test UTF-8 validation of received Text frames using a 1006 // mock WebSocketStream. 1007 class WebSocketChannelReceiveUtf8Test : public WebSocketChannelStreamTest { 1008 public: 1009 virtual void SetUp() { 1010 // For the purpose of the tests using this fixture, it doesn't matter 1011 // whether these methods are called or not. 1012 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1013 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 1014 } 1015 }; 1016 1017 // Simple test that everything that should be passed to the creator function is 1018 // passed to the creator function. 1019 TEST_F(WebSocketChannelTest, EverythingIsPassedToTheCreatorFunction) { 1020 connect_data_.socket_url = GURL("ws://example.com/test"); 1021 connect_data_.origin = url::Origin("http://example.com"); 1022 connect_data_.requested_subprotocols.push_back("Sinbad"); 1023 1024 CreateChannelAndConnect(); 1025 1026 const ArgumentCopyingWebSocketStreamCreator& actual = connect_data_.creator; 1027 1028 EXPECT_EQ(&connect_data_.url_request_context, actual.url_request_context); 1029 1030 EXPECT_EQ(connect_data_.socket_url, actual.socket_url); 1031 EXPECT_EQ(connect_data_.requested_subprotocols, 1032 actual.requested_subprotocols); 1033 EXPECT_EQ(connect_data_.origin.string(), actual.origin.string()); 1034 } 1035 1036 // Verify that calling SendFlowControl before the connection is established does 1037 // not cause a crash. 1038 TEST_F(WebSocketChannelTest, SendFlowControlDuringHandshakeOkay) { 1039 CreateChannelAndConnect(); 1040 ASSERT_TRUE(channel_); 1041 channel_->SendFlowControl(65536); 1042 } 1043 1044 // Any WebSocketEventInterface methods can delete the WebSocketChannel and 1045 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to 1046 // verify that there are no use-after-free bugs when this happens. Problems will 1047 // probably only be found when running under Address Sanitizer or a similar 1048 // tool. 1049 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { 1050 CreateChannelAndConnect(); 1051 EXPECT_TRUE(channel_); 1052 connect_data_.creator.connect_delegate->OnFailure("bye"); 1053 EXPECT_EQ(NULL, channel_.get()); 1054 } 1055 1056 // Deletion is possible (due to IPC failure) even if the connect succeeds. 1057 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) { 1058 CreateChannelAndConnectSuccessfully(); 1059 EXPECT_EQ(NULL, channel_.get()); 1060 } 1061 1062 TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) { 1063 scoped_ptr<ReadableFakeWebSocketStream> stream( 1064 new ReadableFakeWebSocketStream); 1065 static const InitFrame frames[] = { 1066 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1067 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1068 set_stream(stream.Pass()); 1069 deleting_ = EVENT_ON_DATA_FRAME; 1070 1071 CreateChannelAndConnectSuccessfully(); 1072 EXPECT_EQ(NULL, channel_.get()); 1073 } 1074 1075 TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) { 1076 scoped_ptr<ReadableFakeWebSocketStream> stream( 1077 new ReadableFakeWebSocketStream); 1078 static const InitFrame frames[] = { 1079 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1080 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1081 set_stream(stream.Pass()); 1082 deleting_ = EVENT_ON_DATA_FRAME; 1083 1084 CreateChannelAndConnectSuccessfully(); 1085 EXPECT_TRUE(channel_); 1086 base::MessageLoop::current()->RunUntilIdle(); 1087 EXPECT_EQ(NULL, channel_.get()); 1088 } 1089 1090 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) { 1091 deleting_ = EVENT_ON_FLOW_CONTROL; 1092 1093 CreateChannelAndConnectSuccessfully(); 1094 EXPECT_EQ(NULL, channel_.get()); 1095 } 1096 1097 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) { 1098 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1099 // Avoid deleting the channel yet. 1100 deleting_ = EVENT_ON_FAIL_CHANNEL | EVENT_ON_DROP_CHANNEL; 1101 CreateChannelAndConnectSuccessfully(); 1102 ASSERT_TRUE(channel_); 1103 deleting_ = EVENT_ON_FLOW_CONTROL; 1104 channel_->SendFrame(true, 1105 WebSocketFrameHeader::kOpCodeText, 1106 std::vector<char>(kDefaultInitialQuota, 'B')); 1107 EXPECT_EQ(NULL, channel_.get()); 1108 } 1109 1110 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) { 1111 scoped_ptr<ReadableFakeWebSocketStream> stream( 1112 new ReadableFakeWebSocketStream); 1113 static const InitFrame frames[] = { 1114 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1115 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 1116 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1117 set_stream(stream.Pass()); 1118 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; 1119 CreateChannelAndConnectSuccessfully(); 1120 EXPECT_EQ(NULL, channel_.get()); 1121 } 1122 1123 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) { 1124 scoped_ptr<ReadableFakeWebSocketStream> stream( 1125 new ReadableFakeWebSocketStream); 1126 static const InitFrame frames[] = { 1127 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1128 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 1129 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1130 set_stream(stream.Pass()); 1131 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; 1132 CreateChannelAndConnectSuccessfully(); 1133 ASSERT_TRUE(channel_); 1134 base::MessageLoop::current()->RunUntilIdle(); 1135 EXPECT_EQ(NULL, channel_.get()); 1136 } 1137 1138 TEST_F(WebSocketChannelDeletingTest, OnDropChannelWriteError) { 1139 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); 1140 deleting_ = EVENT_ON_DROP_CHANNEL; 1141 CreateChannelAndConnectSuccessfully(); 1142 ASSERT_TRUE(channel_); 1143 channel_->SendFrame( 1144 true, WebSocketFrameHeader::kOpCodeText, AsVector("this will fail")); 1145 EXPECT_EQ(NULL, channel_.get()); 1146 } 1147 1148 TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) { 1149 scoped_ptr<ReadableFakeWebSocketStream> stream( 1150 new ReadableFakeWebSocketStream); 1151 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1152 ERR_FAILED); 1153 set_stream(stream.Pass()); 1154 deleting_ = EVENT_ON_DROP_CHANNEL; 1155 CreateChannelAndConnectSuccessfully(); 1156 ASSERT_TRUE(channel_); 1157 base::MessageLoop::current()->RunUntilIdle(); 1158 EXPECT_EQ(NULL, channel_.get()); 1159 } 1160 1161 TEST_F(WebSocketChannelDeletingTest, OnNotifyStartOpeningHandshakeError) { 1162 scoped_ptr<ReadableFakeWebSocketStream> stream( 1163 new ReadableFakeWebSocketStream); 1164 static const InitFrame frames[] = { 1165 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1166 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1167 set_stream(stream.Pass()); 1168 deleting_ = EVENT_ON_START_OPENING_HANDSHAKE; 1169 1170 CreateChannelAndConnectSuccessfully(); 1171 ASSERT_TRUE(channel_); 1172 channel_->OnStartOpeningHandshake(scoped_ptr<WebSocketHandshakeRequestInfo>( 1173 new WebSocketHandshakeRequestInfo(GURL("http://www.example.com/"), 1174 base::Time()))); 1175 base::MessageLoop::current()->RunUntilIdle(); 1176 EXPECT_EQ(NULL, channel_.get()); 1177 } 1178 1179 TEST_F(WebSocketChannelDeletingTest, OnNotifyFinishOpeningHandshakeError) { 1180 scoped_ptr<ReadableFakeWebSocketStream> stream( 1181 new ReadableFakeWebSocketStream); 1182 static const InitFrame frames[] = { 1183 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1184 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1185 set_stream(stream.Pass()); 1186 deleting_ = EVENT_ON_FINISH_OPENING_HANDSHAKE; 1187 1188 CreateChannelAndConnectSuccessfully(); 1189 ASSERT_TRUE(channel_); 1190 scoped_refptr<HttpResponseHeaders> response_headers( 1191 new HttpResponseHeaders("")); 1192 channel_->OnFinishOpeningHandshake(scoped_ptr<WebSocketHandshakeResponseInfo>( 1193 new WebSocketHandshakeResponseInfo(GURL("http://www.example.com/"), 1194 200, 1195 "OK", 1196 response_headers, 1197 base::Time()))); 1198 base::MessageLoop::current()->RunUntilIdle(); 1199 EXPECT_EQ(NULL, channel_.get()); 1200 } 1201 1202 TEST_F(WebSocketChannelDeletingTest, FailChannelInSendFrame) { 1203 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1204 deleting_ = EVENT_ON_FAIL_CHANNEL; 1205 CreateChannelAndConnectSuccessfully(); 1206 ASSERT_TRUE(channel_); 1207 channel_->SendFrame(true, 1208 WebSocketFrameHeader::kOpCodeText, 1209 std::vector<char>(kDefaultInitialQuota * 2, 'T')); 1210 EXPECT_EQ(NULL, channel_.get()); 1211 } 1212 1213 TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) { 1214 scoped_ptr<ReadableFakeWebSocketStream> stream( 1215 new ReadableFakeWebSocketStream); 1216 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1217 ERR_WS_PROTOCOL_ERROR); 1218 set_stream(stream.Pass()); 1219 deleting_ = EVENT_ON_FAIL_CHANNEL; 1220 CreateChannelAndConnectSuccessfully(); 1221 ASSERT_TRUE(channel_); 1222 base::MessageLoop::current()->RunUntilIdle(); 1223 EXPECT_EQ(NULL, channel_.get()); 1224 } 1225 1226 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) { 1227 scoped_ptr<ReadableFakeWebSocketStream> stream( 1228 new ReadableFakeWebSocketStream); 1229 static const InitFrame frames[] = { 1230 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; 1231 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1232 set_stream(stream.Pass()); 1233 deleting_ = EVENT_ON_FAIL_CHANNEL; 1234 1235 CreateChannelAndConnectSuccessfully(); 1236 EXPECT_EQ(NULL, channel_.get()); 1237 } 1238 1239 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) { 1240 scoped_ptr<ReadableFakeWebSocketStream> stream( 1241 new ReadableFakeWebSocketStream); 1242 static const InitFrame frames[] = { 1243 {FINAL_FRAME, 0xF, NOT_MASKED, ""}}; 1244 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1245 set_stream(stream.Pass()); 1246 deleting_ = EVENT_ON_FAIL_CHANNEL; 1247 1248 CreateChannelAndConnectSuccessfully(); 1249 EXPECT_EQ(NULL, channel_.get()); 1250 } 1251 1252 // Version of above test with NULL data. 1253 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrameNull) { 1254 scoped_ptr<ReadableFakeWebSocketStream> stream( 1255 new ReadableFakeWebSocketStream); 1256 static const InitFrame frames[] = { 1257 {FINAL_FRAME, 0xF, NOT_MASKED, NULL}}; 1258 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1259 set_stream(stream.Pass()); 1260 deleting_ = EVENT_ON_FAIL_CHANNEL; 1261 1262 CreateChannelAndConnectSuccessfully(); 1263 EXPECT_EQ(NULL, channel_.get()); 1264 } 1265 1266 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) { 1267 scoped_ptr<ReadableFakeWebSocketStream> stream( 1268 new ReadableFakeWebSocketStream); 1269 static const InitFrame frames[] = { 1270 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 1271 CLOSE_DATA(NORMAL_CLOSURE, "Success")}, 1272 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; 1273 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1274 set_stream(stream.Pass()); 1275 deleting_ = EVENT_ON_FAIL_CHANNEL; 1276 1277 CreateChannelAndConnectSuccessfully(); 1278 EXPECT_EQ(NULL, channel_.get()); 1279 } 1280 1281 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterCloseNull) { 1282 scoped_ptr<ReadableFakeWebSocketStream> stream( 1283 new ReadableFakeWebSocketStream); 1284 static const InitFrame frames[] = { 1285 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 1286 CLOSE_DATA(NORMAL_CLOSURE, "Success")}, 1287 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}}; 1288 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1289 set_stream(stream.Pass()); 1290 deleting_ = EVENT_ON_FAIL_CHANNEL; 1291 1292 CreateChannelAndConnectSuccessfully(); 1293 EXPECT_EQ(NULL, channel_.get()); 1294 } 1295 1296 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) { 1297 scoped_ptr<ReadableFakeWebSocketStream> stream( 1298 new ReadableFakeWebSocketStream); 1299 static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}}; 1300 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1301 set_stream(stream.Pass()); 1302 deleting_ = EVENT_ON_FAIL_CHANNEL; 1303 1304 CreateChannelAndConnectSuccessfully(); 1305 EXPECT_EQ(NULL, channel_.get()); 1306 } 1307 1308 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCodeNull) { 1309 scoped_ptr<ReadableFakeWebSocketStream> stream( 1310 new ReadableFakeWebSocketStream); 1311 static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, NULL}}; 1312 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1313 set_stream(stream.Pass()); 1314 deleting_ = EVENT_ON_FAIL_CHANNEL; 1315 1316 CreateChannelAndConnectSuccessfully(); 1317 EXPECT_EQ(NULL, channel_.get()); 1318 } 1319 1320 TEST_F(WebSocketChannelDeletingTest, FailChannelDueInvalidCloseReason) { 1321 scoped_ptr<ReadableFakeWebSocketStream> stream( 1322 new ReadableFakeWebSocketStream); 1323 static const InitFrame frames[] = { 1324 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1325 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}}; 1326 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1327 set_stream(stream.Pass()); 1328 deleting_ = EVENT_ON_FAIL_CHANNEL; 1329 1330 CreateChannelAndConnectSuccessfully(); 1331 EXPECT_EQ(NULL, channel_.get()); 1332 } 1333 1334 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { 1335 // false means success. 1336 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "", "")); 1337 // OnFlowControl is always called immediately after connect to provide initial 1338 // quota to the renderer. 1339 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1340 1341 CreateChannelAndConnect(); 1342 1343 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 1344 } 1345 1346 TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) { 1347 EXPECT_CALL(*event_interface_, OnFailChannel("hello")); 1348 1349 CreateChannelAndConnect(); 1350 1351 connect_data_.creator.connect_delegate->OnFailure("hello"); 1352 } 1353 1354 TEST_F(WebSocketChannelEventInterfaceTest, NonWebSocketSchemeRejected) { 1355 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "", "")); 1356 connect_data_.socket_url = GURL("http://www.google.com/"); 1357 CreateChannelAndConnect(); 1358 } 1359 1360 TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { 1361 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "Bob", "")); 1362 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1363 1364 CreateChannelAndConnect(); 1365 1366 connect_data_.creator.connect_delegate->OnSuccess( 1367 scoped_ptr<WebSocketStream>(new FakeWebSocketStream("Bob", ""))); 1368 } 1369 1370 TEST_F(WebSocketChannelEventInterfaceTest, ExtensionsPassed) { 1371 EXPECT_CALL(*event_interface_, 1372 OnAddChannelResponse(false, "", "extension1, extension2")); 1373 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1374 1375 CreateChannelAndConnect(); 1376 1377 connect_data_.creator.connect_delegate->OnSuccess(scoped_ptr<WebSocketStream>( 1378 new FakeWebSocketStream("", "extension1, extension2"))); 1379 } 1380 1381 // The first frames from the server can arrive together with the handshake, in 1382 // which case they will be available as soon as ReadFrames() is called the first 1383 // time. 1384 TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) { 1385 scoped_ptr<ReadableFakeWebSocketStream> stream( 1386 new ReadableFakeWebSocketStream); 1387 static const InitFrame frames[] = { 1388 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1389 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1390 set_stream(stream.Pass()); 1391 { 1392 InSequence s; 1393 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1394 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1395 EXPECT_CALL( 1396 *event_interface_, 1397 OnDataFrame( 1398 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 1399 } 1400 1401 CreateChannelAndConnectSuccessfully(); 1402 } 1403 1404 // A remote server could accept the handshake, but then immediately send a 1405 // Close frame. 1406 TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) { 1407 scoped_ptr<ReadableFakeWebSocketStream> stream( 1408 new ReadableFakeWebSocketStream); 1409 static const InitFrame frames[] = { 1410 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1411 NOT_MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}}; 1412 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1413 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1414 ERR_CONNECTION_CLOSED); 1415 set_stream(stream.Pass()); 1416 { 1417 InSequence s; 1418 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1419 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1420 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1421 EXPECT_CALL( 1422 *event_interface_, 1423 OnDropChannel( 1424 true, kWebSocketErrorInternalServerError, "Internal Server Error")); 1425 } 1426 1427 CreateChannelAndConnectSuccessfully(); 1428 } 1429 1430 // A remote server could close the connection immediately after sending the 1431 // handshake response (most likely a bug in the server). 1432 TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) { 1433 scoped_ptr<ReadableFakeWebSocketStream> stream( 1434 new ReadableFakeWebSocketStream); 1435 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1436 ERR_CONNECTION_CLOSED); 1437 set_stream(stream.Pass()); 1438 { 1439 InSequence s; 1440 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1441 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1442 EXPECT_CALL(*event_interface_, 1443 OnDropChannel(false, kWebSocketErrorAbnormalClosure, _)); 1444 } 1445 1446 CreateChannelAndConnectSuccessfully(); 1447 } 1448 1449 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { 1450 scoped_ptr<ReadableFakeWebSocketStream> stream( 1451 new ReadableFakeWebSocketStream); 1452 static const InitFrame frames[] = { 1453 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1454 // We use this checkpoint object to verify that the callback isn't called 1455 // until we expect it to be. 1456 Checkpoint checkpoint; 1457 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1458 set_stream(stream.Pass()); 1459 { 1460 InSequence s; 1461 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1462 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1463 EXPECT_CALL(checkpoint, Call(1)); 1464 EXPECT_CALL( 1465 *event_interface_, 1466 OnDataFrame( 1467 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 1468 EXPECT_CALL(checkpoint, Call(2)); 1469 } 1470 1471 CreateChannelAndConnectSuccessfully(); 1472 checkpoint.Call(1); 1473 base::MessageLoop::current()->RunUntilIdle(); 1474 checkpoint.Call(2); 1475 } 1476 1477 // Extra data can arrive while a read is being processed, resulting in the next 1478 // read completing synchronously. 1479 TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) { 1480 scoped_ptr<ReadableFakeWebSocketStream> stream( 1481 new ReadableFakeWebSocketStream); 1482 static const InitFrame frames1[] = { 1483 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1484 static const InitFrame frames2[] = { 1485 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "WORLD"}}; 1486 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); 1487 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames2); 1488 set_stream(stream.Pass()); 1489 { 1490 InSequence s; 1491 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1492 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1493 EXPECT_CALL( 1494 *event_interface_, 1495 OnDataFrame( 1496 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 1497 EXPECT_CALL( 1498 *event_interface_, 1499 OnDataFrame( 1500 true, WebSocketFrameHeader::kOpCodeText, AsVector("WORLD"))); 1501 } 1502 1503 CreateChannelAndConnectSuccessfully(); 1504 base::MessageLoop::current()->RunUntilIdle(); 1505 } 1506 1507 // Data frames are delivered the same regardless of how many reads they arrive 1508 // as. 1509 TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) { 1510 scoped_ptr<ReadableFakeWebSocketStream> stream( 1511 new ReadableFakeWebSocketStream); 1512 // Here we have one message which arrived in five frames split across three 1513 // reads. It may have been reframed on arrival, but this class doesn't care 1514 // about that. 1515 static const InitFrame frames1[] = { 1516 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "THREE"}, 1517 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1518 NOT_MASKED, " "}}; 1519 static const InitFrame frames2[] = { 1520 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1521 NOT_MASKED, "SMALL"}}; 1522 static const InitFrame frames3[] = { 1523 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1524 NOT_MASKED, " "}, 1525 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1526 NOT_MASKED, "FRAMES"}}; 1527 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); 1528 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2); 1529 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3); 1530 set_stream(stream.Pass()); 1531 { 1532 InSequence s; 1533 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1534 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1535 EXPECT_CALL( 1536 *event_interface_, 1537 OnDataFrame( 1538 false, WebSocketFrameHeader::kOpCodeText, AsVector("THREE"))); 1539 EXPECT_CALL( 1540 *event_interface_, 1541 OnDataFrame( 1542 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector(" "))); 1543 EXPECT_CALL(*event_interface_, 1544 OnDataFrame(false, 1545 WebSocketFrameHeader::kOpCodeContinuation, 1546 AsVector("SMALL"))); 1547 EXPECT_CALL( 1548 *event_interface_, 1549 OnDataFrame( 1550 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector(" "))); 1551 EXPECT_CALL(*event_interface_, 1552 OnDataFrame(true, 1553 WebSocketFrameHeader::kOpCodeContinuation, 1554 AsVector("FRAMES"))); 1555 } 1556 1557 CreateChannelAndConnectSuccessfully(); 1558 base::MessageLoop::current()->RunUntilIdle(); 1559 } 1560 1561 // A message can consist of one frame with NULL payload. 1562 TEST_F(WebSocketChannelEventInterfaceTest, NullMessage) { 1563 scoped_ptr<ReadableFakeWebSocketStream> stream( 1564 new ReadableFakeWebSocketStream); 1565 static const InitFrame frames[] = { 1566 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, NULL}}; 1567 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1568 set_stream(stream.Pass()); 1569 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1570 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1571 EXPECT_CALL( 1572 *event_interface_, 1573 OnDataFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector(""))); 1574 CreateChannelAndConnectSuccessfully(); 1575 } 1576 1577 // Connection closed by the remote host without a closing handshake. 1578 TEST_F(WebSocketChannelEventInterfaceTest, AsyncAbnormalClosure) { 1579 scoped_ptr<ReadableFakeWebSocketStream> stream( 1580 new ReadableFakeWebSocketStream); 1581 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1582 ERR_CONNECTION_CLOSED); 1583 set_stream(stream.Pass()); 1584 { 1585 InSequence s; 1586 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1587 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1588 EXPECT_CALL(*event_interface_, 1589 OnDropChannel(false, kWebSocketErrorAbnormalClosure, _)); 1590 } 1591 1592 CreateChannelAndConnectSuccessfully(); 1593 base::MessageLoop::current()->RunUntilIdle(); 1594 } 1595 1596 // A connection reset should produce the same event as an unexpected closure. 1597 TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) { 1598 scoped_ptr<ReadableFakeWebSocketStream> stream( 1599 new ReadableFakeWebSocketStream); 1600 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1601 ERR_CONNECTION_RESET); 1602 set_stream(stream.Pass()); 1603 { 1604 InSequence s; 1605 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1606 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1607 EXPECT_CALL(*event_interface_, 1608 OnDropChannel(false, kWebSocketErrorAbnormalClosure, _)); 1609 } 1610 1611 CreateChannelAndConnectSuccessfully(); 1612 base::MessageLoop::current()->RunUntilIdle(); 1613 } 1614 1615 // RFC6455 5.1 "A client MUST close a connection if it detects a masked frame." 1616 TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) { 1617 scoped_ptr<ReadableFakeWebSocketStream> stream( 1618 new ReadableFakeWebSocketStream); 1619 static const InitFrame frames[] = { 1620 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; 1621 1622 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1623 set_stream(stream.Pass()); 1624 { 1625 InSequence s; 1626 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1627 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1628 EXPECT_CALL( 1629 *event_interface_, 1630 OnFailChannel( 1631 "A server must not mask any frames that it sends to the client.")); 1632 } 1633 1634 CreateChannelAndConnectSuccessfully(); 1635 base::MessageLoop::current()->RunUntilIdle(); 1636 } 1637 1638 // RFC6455 5.2 "If an unknown opcode is received, the receiving endpoint MUST 1639 // _Fail the WebSocket Connection_." 1640 TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) { 1641 scoped_ptr<ReadableFakeWebSocketStream> stream( 1642 new ReadableFakeWebSocketStream); 1643 static const InitFrame frames[] = {{FINAL_FRAME, 4, NOT_MASKED, "HELLO"}}; 1644 1645 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1646 set_stream(stream.Pass()); 1647 { 1648 InSequence s; 1649 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1650 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1651 EXPECT_CALL(*event_interface_, 1652 OnFailChannel("Unrecognized frame opcode: 4")); 1653 } 1654 1655 CreateChannelAndConnectSuccessfully(); 1656 base::MessageLoop::current()->RunUntilIdle(); 1657 } 1658 1659 // RFC6455 5.4 "Control frames ... MAY be injected in the middle of a 1660 // fragmented message." 1661 TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) { 1662 scoped_ptr<ReadableFakeWebSocketStream> stream( 1663 new ReadableFakeWebSocketStream); 1664 // We have one message of type Text split into two frames. In the middle is a 1665 // control message of type Pong. 1666 static const InitFrame frames1[] = { 1667 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 1668 NOT_MASKED, "SPLIT "}}; 1669 static const InitFrame frames2[] = { 1670 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; 1671 static const InitFrame frames3[] = { 1672 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1673 NOT_MASKED, "MESSAGE"}}; 1674 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); 1675 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2); 1676 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3); 1677 set_stream(stream.Pass()); 1678 { 1679 InSequence s; 1680 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1681 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1682 EXPECT_CALL( 1683 *event_interface_, 1684 OnDataFrame( 1685 false, WebSocketFrameHeader::kOpCodeText, AsVector("SPLIT "))); 1686 EXPECT_CALL(*event_interface_, 1687 OnDataFrame(true, 1688 WebSocketFrameHeader::kOpCodeContinuation, 1689 AsVector("MESSAGE"))); 1690 } 1691 1692 CreateChannelAndConnectSuccessfully(); 1693 base::MessageLoop::current()->RunUntilIdle(); 1694 } 1695 1696 // It seems redundant to repeat the entirety of the above test, so just test a 1697 // Pong with NULL data. 1698 TEST_F(WebSocketChannelEventInterfaceTest, PongWithNullData) { 1699 scoped_ptr<ReadableFakeWebSocketStream> stream( 1700 new ReadableFakeWebSocketStream); 1701 static const InitFrame frames[] = { 1702 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}}; 1703 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1704 set_stream(stream.Pass()); 1705 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1706 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1707 1708 CreateChannelAndConnectSuccessfully(); 1709 base::MessageLoop::current()->RunUntilIdle(); 1710 } 1711 1712 // If a frame has an invalid header, then the connection is closed and 1713 // subsequent frames must not trigger events. 1714 TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) { 1715 scoped_ptr<ReadableFakeWebSocketStream> stream( 1716 new ReadableFakeWebSocketStream); 1717 static const InitFrame frames[] = { 1718 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}, 1719 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, " WORLD"}}; 1720 1721 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1722 set_stream(stream.Pass()); 1723 { 1724 InSequence s; 1725 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1726 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1727 EXPECT_CALL( 1728 *event_interface_, 1729 OnFailChannel( 1730 "A server must not mask any frames that it sends to the client.")); 1731 } 1732 1733 CreateChannelAndConnectSuccessfully(); 1734 base::MessageLoop::current()->RunUntilIdle(); 1735 } 1736 1737 // If the renderer sends lots of small writes, we don't want to update the quota 1738 // for each one. 1739 TEST_F(WebSocketChannelEventInterfaceTest, SmallWriteDoesntUpdateQuota) { 1740 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1741 { 1742 InSequence s; 1743 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1744 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1745 } 1746 1747 CreateChannelAndConnectSuccessfully(); 1748 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B")); 1749 } 1750 1751 // If we send enough to go below send_quota_low_water_mask_ we should get our 1752 // quota refreshed. 1753 TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) { 1754 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1755 // We use this checkpoint object to verify that the quota update comes after 1756 // the write. 1757 Checkpoint checkpoint; 1758 { 1759 InSequence s; 1760 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1761 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1762 EXPECT_CALL(checkpoint, Call(1)); 1763 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1764 EXPECT_CALL(checkpoint, Call(2)); 1765 } 1766 1767 CreateChannelAndConnectSuccessfully(); 1768 checkpoint.Call(1); 1769 channel_->SendFrame(true, 1770 WebSocketFrameHeader::kOpCodeText, 1771 std::vector<char>(kDefaultInitialQuota, 'B')); 1772 checkpoint.Call(2); 1773 } 1774 1775 // Verify that our quota actually is refreshed when we are told it is. 1776 TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) { 1777 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1778 Checkpoint checkpoint; 1779 { 1780 InSequence s; 1781 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1782 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1783 EXPECT_CALL(checkpoint, Call(1)); 1784 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1785 EXPECT_CALL(checkpoint, Call(2)); 1786 // If quota was not really refreshed, we would get an OnDropChannel() 1787 // message. 1788 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1789 EXPECT_CALL(checkpoint, Call(3)); 1790 } 1791 1792 CreateChannelAndConnectSuccessfully(); 1793 checkpoint.Call(1); 1794 channel_->SendFrame(true, 1795 WebSocketFrameHeader::kOpCodeText, 1796 std::vector<char>(kDefaultQuotaRefreshTrigger, 'D')); 1797 checkpoint.Call(2); 1798 // We should have received more quota at this point. 1799 channel_->SendFrame(true, 1800 WebSocketFrameHeader::kOpCodeText, 1801 std::vector<char>(kDefaultQuotaRefreshTrigger, 'E')); 1802 checkpoint.Call(3); 1803 } 1804 1805 // If we send more than the available quota then the connection will be closed 1806 // with an error. 1807 TEST_F(WebSocketChannelEventInterfaceTest, WriteOverQuotaIsRejected) { 1808 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1809 { 1810 InSequence s; 1811 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1812 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); 1813 EXPECT_CALL(*event_interface_, OnFailChannel("Send quota exceeded")); 1814 } 1815 1816 CreateChannelAndConnectSuccessfully(); 1817 channel_->SendFrame(true, 1818 WebSocketFrameHeader::kOpCodeText, 1819 std::vector<char>(kDefaultInitialQuota + 1, 'C')); 1820 } 1821 1822 // If a write fails, the channel is dropped. 1823 TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) { 1824 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); 1825 Checkpoint checkpoint; 1826 { 1827 InSequence s; 1828 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1829 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1830 EXPECT_CALL(checkpoint, Call(1)); 1831 EXPECT_CALL(*event_interface_, 1832 OnDropChannel(false, kWebSocketErrorAbnormalClosure, _)); 1833 EXPECT_CALL(checkpoint, Call(2)); 1834 } 1835 1836 CreateChannelAndConnectSuccessfully(); 1837 checkpoint.Call(1); 1838 1839 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("H")); 1840 checkpoint.Call(2); 1841 } 1842 1843 // OnDropChannel() is called exactly once when StartClosingHandshake() is used. 1844 TEST_F(WebSocketChannelEventInterfaceTest, SendCloseDropsChannel) { 1845 set_stream(make_scoped_ptr(new EchoeyFakeWebSocketStream)); 1846 { 1847 InSequence s; 1848 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1849 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1850 EXPECT_CALL(*event_interface_, 1851 OnDropChannel(true, kWebSocketNormalClosure, "Fred")); 1852 } 1853 1854 CreateChannelAndConnectSuccessfully(); 1855 1856 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Fred"); 1857 base::MessageLoop::current()->RunUntilIdle(); 1858 } 1859 1860 // StartClosingHandshake() also works before connection completes, and calls 1861 // OnDropChannel. 1862 TEST_F(WebSocketChannelEventInterfaceTest, CloseDuringConnection) { 1863 EXPECT_CALL(*event_interface_, 1864 OnDropChannel(false, kWebSocketErrorAbnormalClosure, "")); 1865 1866 CreateChannelAndConnect(); 1867 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Joe"); 1868 } 1869 1870 // OnDropChannel() is only called once when a write() on the socket triggers a 1871 // connection reset. 1872 TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) { 1873 set_stream(make_scoped_ptr(new ResetOnWriteFakeWebSocketStream)); 1874 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1875 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1876 1877 EXPECT_CALL(*event_interface_, 1878 OnDropChannel(false, kWebSocketErrorAbnormalClosure, "")) 1879 .Times(1); 1880 1881 CreateChannelAndConnectSuccessfully(); 1882 1883 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("yt?")); 1884 base::MessageLoop::current()->RunUntilIdle(); 1885 } 1886 1887 // When the remote server sends a Close frame with an empty payload, 1888 // WebSocketChannel should report code 1005, kWebSocketErrorNoStatusReceived. 1889 TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) { 1890 scoped_ptr<ReadableFakeWebSocketStream> stream( 1891 new ReadableFakeWebSocketStream); 1892 static const InitFrame frames[] = { 1893 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; 1894 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1895 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1896 ERR_CONNECTION_CLOSED); 1897 set_stream(stream.Pass()); 1898 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1899 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1900 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1901 EXPECT_CALL(*event_interface_, 1902 OnDropChannel(true, kWebSocketErrorNoStatusReceived, _)); 1903 1904 CreateChannelAndConnectSuccessfully(); 1905 } 1906 1907 // A version of the above test with NULL payload. 1908 TEST_F(WebSocketChannelEventInterfaceTest, 1909 CloseWithNullPayloadGivesStatus1005) { 1910 scoped_ptr<ReadableFakeWebSocketStream> stream( 1911 new ReadableFakeWebSocketStream); 1912 static const InitFrame frames[] = { 1913 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, NULL}}; 1914 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1915 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1916 ERR_CONNECTION_CLOSED); 1917 set_stream(stream.Pass()); 1918 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1919 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1920 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1921 EXPECT_CALL(*event_interface_, 1922 OnDropChannel(true, kWebSocketErrorNoStatusReceived, _)); 1923 1924 CreateChannelAndConnectSuccessfully(); 1925 } 1926 1927 // If ReadFrames() returns ERR_WS_PROTOCOL_ERROR, then the connection must be 1928 // failed. 1929 TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) { 1930 scoped_ptr<ReadableFakeWebSocketStream> stream( 1931 new ReadableFakeWebSocketStream); 1932 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1933 ERR_WS_PROTOCOL_ERROR); 1934 set_stream(stream.Pass()); 1935 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1936 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1937 1938 EXPECT_CALL(*event_interface_, OnFailChannel("Invalid frame header")); 1939 1940 CreateChannelAndConnectSuccessfully(); 1941 } 1942 1943 // Async version of above test. 1944 TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) { 1945 scoped_ptr<ReadableFakeWebSocketStream> stream( 1946 new ReadableFakeWebSocketStream); 1947 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1948 ERR_WS_PROTOCOL_ERROR); 1949 set_stream(stream.Pass()); 1950 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1951 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1952 1953 EXPECT_CALL(*event_interface_, OnFailChannel("Invalid frame header")); 1954 1955 CreateChannelAndConnectSuccessfully(); 1956 base::MessageLoop::current()->RunUntilIdle(); 1957 } 1958 1959 TEST_F(WebSocketChannelEventInterfaceTest, StartHandshakeRequest) { 1960 { 1961 InSequence s; 1962 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1963 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1964 EXPECT_CALL(*event_interface_, OnStartOpeningHandshakeCalled()); 1965 } 1966 1967 CreateChannelAndConnectSuccessfully(); 1968 1969 scoped_ptr<WebSocketHandshakeRequestInfo> request_info( 1970 new WebSocketHandshakeRequestInfo(GURL("ws://www.example.com/"), 1971 base::Time())); 1972 connect_data_.creator.connect_delegate->OnStartOpeningHandshake( 1973 request_info.Pass()); 1974 1975 base::MessageLoop::current()->RunUntilIdle(); 1976 } 1977 1978 TEST_F(WebSocketChannelEventInterfaceTest, FinishHandshakeRequest) { 1979 { 1980 InSequence s; 1981 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 1982 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1983 EXPECT_CALL(*event_interface_, OnFinishOpeningHandshakeCalled()); 1984 } 1985 1986 CreateChannelAndConnectSuccessfully(); 1987 1988 scoped_refptr<HttpResponseHeaders> response_headers( 1989 new HttpResponseHeaders("")); 1990 scoped_ptr<WebSocketHandshakeResponseInfo> response_info( 1991 new WebSocketHandshakeResponseInfo(GURL("ws://www.example.com/"), 1992 200, 1993 "OK", 1994 response_headers, 1995 base::Time())); 1996 connect_data_.creator.connect_delegate->OnFinishOpeningHandshake( 1997 response_info.Pass()); 1998 base::MessageLoop::current()->RunUntilIdle(); 1999 } 2000 2001 TEST_F(WebSocketChannelEventInterfaceTest, FailJustAfterHandshake) { 2002 { 2003 InSequence s; 2004 EXPECT_CALL(*event_interface_, OnStartOpeningHandshakeCalled()); 2005 EXPECT_CALL(*event_interface_, OnFinishOpeningHandshakeCalled()); 2006 EXPECT_CALL(*event_interface_, OnFailChannel("bye")); 2007 } 2008 2009 CreateChannelAndConnect(); 2010 2011 WebSocketStream::ConnectDelegate* connect_delegate = 2012 connect_data_.creator.connect_delegate.get(); 2013 GURL url("ws://www.example.com/"); 2014 scoped_ptr<WebSocketHandshakeRequestInfo> request_info( 2015 new WebSocketHandshakeRequestInfo(url, base::Time())); 2016 scoped_refptr<HttpResponseHeaders> response_headers( 2017 new HttpResponseHeaders("")); 2018 scoped_ptr<WebSocketHandshakeResponseInfo> response_info( 2019 new WebSocketHandshakeResponseInfo(url, 2020 200, 2021 "OK", 2022 response_headers, 2023 base::Time())); 2024 connect_delegate->OnStartOpeningHandshake(request_info.Pass()); 2025 connect_delegate->OnFinishOpeningHandshake(response_info.Pass()); 2026 2027 connect_delegate->OnFailure("bye"); 2028 base::MessageLoop::current()->RunUntilIdle(); 2029 } 2030 2031 // Any frame after close is invalid. This test uses a Text frame. See also 2032 // test "PingAfterCloseIfRejected". 2033 TEST_F(WebSocketChannelEventInterfaceTest, DataAfterCloseIsRejected) { 2034 scoped_ptr<ReadableFakeWebSocketStream> stream( 2035 new ReadableFakeWebSocketStream); 2036 static const InitFrame frames[] = { 2037 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 2038 CLOSE_DATA(NORMAL_CLOSURE, "OK")}, 2039 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "Payload"}}; 2040 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2041 set_stream(stream.Pass()); 2042 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2043 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2044 2045 { 2046 InSequence s; 2047 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 2048 EXPECT_CALL(*event_interface_, 2049 OnFailChannel("Data frame received after close")); 2050 } 2051 2052 CreateChannelAndConnectSuccessfully(); 2053 } 2054 2055 // A Close frame with a one-byte payload elicits a specific console error 2056 // message. 2057 TEST_F(WebSocketChannelEventInterfaceTest, OneByteClosePayloadMessage) { 2058 scoped_ptr<ReadableFakeWebSocketStream> stream( 2059 new ReadableFakeWebSocketStream); 2060 static const InitFrame frames[] = { 2061 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, "\x03"}}; 2062 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2063 set_stream(stream.Pass()); 2064 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2065 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2066 EXPECT_CALL( 2067 *event_interface_, 2068 OnFailChannel( 2069 "Received a broken close frame containing an invalid size body.")); 2070 2071 CreateChannelAndConnectSuccessfully(); 2072 } 2073 2074 // A Close frame with a reserved status code also elicits a specific console 2075 // error message. 2076 TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadReservedStatusMessage) { 2077 scoped_ptr<ReadableFakeWebSocketStream> stream( 2078 new ReadableFakeWebSocketStream); 2079 static const InitFrame frames[] = { 2080 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2081 NOT_MASKED, CLOSE_DATA(ABNORMAL_CLOSURE, "Not valid on wire")}}; 2082 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2083 set_stream(stream.Pass()); 2084 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2085 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2086 EXPECT_CALL( 2087 *event_interface_, 2088 OnFailChannel( 2089 "Received a broken close frame containing a reserved status code.")); 2090 2091 CreateChannelAndConnectSuccessfully(); 2092 } 2093 2094 // A Close frame with invalid UTF-8 also elicits a specific console error 2095 // message. 2096 TEST_F(WebSocketChannelEventInterfaceTest, ClosePayloadInvalidReason) { 2097 scoped_ptr<ReadableFakeWebSocketStream> stream( 2098 new ReadableFakeWebSocketStream); 2099 static const InitFrame frames[] = { 2100 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2101 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}}; 2102 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2103 set_stream(stream.Pass()); 2104 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2105 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2106 EXPECT_CALL( 2107 *event_interface_, 2108 OnFailChannel( 2109 "Received a broken close frame containing invalid UTF-8.")); 2110 2111 CreateChannelAndConnectSuccessfully(); 2112 } 2113 2114 // The reserved bits must all be clear on received frames. Extensions should 2115 // clear the bits when they are set correctly before passing on the frame. 2116 TEST_F(WebSocketChannelEventInterfaceTest, ReservedBitsMustNotBeSet) { 2117 scoped_ptr<ReadableFakeWebSocketStream> stream( 2118 new ReadableFakeWebSocketStream); 2119 static const InitFrame frames[] = { 2120 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 2121 NOT_MASKED, "sakana"}}; 2122 // It is not worth adding support for reserved bits to InitFrame just for this 2123 // one test, so set the bit manually. 2124 ScopedVector<WebSocketFrame> raw_frames = CreateFrameVector(frames); 2125 raw_frames[0]->header.reserved1 = true; 2126 stream->PrepareRawReadFrames( 2127 ReadableFakeWebSocketStream::SYNC, OK, raw_frames.Pass()); 2128 set_stream(stream.Pass()); 2129 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2130 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2131 EXPECT_CALL(*event_interface_, 2132 OnFailChannel( 2133 "One or more reserved bits are on: reserved1 = 1, " 2134 "reserved2 = 0, reserved3 = 0")); 2135 2136 CreateChannelAndConnectSuccessfully(); 2137 } 2138 2139 // The closing handshake times out and sends an OnDropChannel event if no 2140 // response to the client Close message is received. 2141 TEST_F(WebSocketChannelEventInterfaceTest, 2142 ClientInitiatedClosingHandshakeTimesOut) { 2143 scoped_ptr<ReadableFakeWebSocketStream> stream( 2144 new ReadableFakeWebSocketStream); 2145 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 2146 ERR_IO_PENDING); 2147 set_stream(stream.Pass()); 2148 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2149 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2150 // This checkpoint object verifies that the OnDropChannel message comes after 2151 // the timeout. 2152 Checkpoint checkpoint; 2153 TestClosure completion; 2154 { 2155 InSequence s; 2156 EXPECT_CALL(checkpoint, Call(1)); 2157 EXPECT_CALL(*event_interface_, 2158 OnDropChannel(false, kWebSocketErrorAbnormalClosure, _)) 2159 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); 2160 } 2161 CreateChannelAndConnectSuccessfully(); 2162 // OneShotTimer is not very friendly to testing; there is no apparent way to 2163 // set an expectation on it. Instead the tests need to infer that the timeout 2164 // was fired by the behaviour of the WebSocketChannel object. 2165 channel_->SetClosingHandshakeTimeoutForTesting( 2166 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); 2167 channel_->StartClosingHandshake(kWebSocketNormalClosure, ""); 2168 checkpoint.Call(1); 2169 completion.WaitForResult(); 2170 } 2171 2172 // The closing handshake times out and sends an OnDropChannel event if a Close 2173 // message is received but the connection isn't closed by the remote host. 2174 TEST_F(WebSocketChannelEventInterfaceTest, 2175 ServerInitiatedClosingHandshakeTimesOut) { 2176 scoped_ptr<ReadableFakeWebSocketStream> stream( 2177 new ReadableFakeWebSocketStream); 2178 static const InitFrame frames[] = { 2179 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2180 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2181 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 2182 set_stream(stream.Pass()); 2183 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2184 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2185 Checkpoint checkpoint; 2186 TestClosure completion; 2187 { 2188 InSequence s; 2189 EXPECT_CALL(checkpoint, Call(1)); 2190 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 2191 EXPECT_CALL(*event_interface_, 2192 OnDropChannel(false, kWebSocketErrorAbnormalClosure, _)) 2193 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); 2194 } 2195 CreateChannelAndConnectSuccessfully(); 2196 channel_->SetClosingHandshakeTimeoutForTesting( 2197 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); 2198 checkpoint.Call(1); 2199 completion.WaitForResult(); 2200 } 2201 2202 // The renderer should provide us with some quota immediately, and then 2203 // WebSocketChannel calls ReadFrames as soon as the stream is available. 2204 TEST_F(WebSocketChannelStreamTest, FlowControlEarly) { 2205 Checkpoint checkpoint; 2206 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2207 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2208 { 2209 InSequence s; 2210 EXPECT_CALL(checkpoint, Call(1)); 2211 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2212 .WillOnce(Return(ERR_IO_PENDING)); 2213 EXPECT_CALL(checkpoint, Call(2)); 2214 } 2215 2216 set_stream(mock_stream_.Pass()); 2217 CreateChannelAndConnect(); 2218 channel_->SendFlowControl(kPlentyOfQuota); 2219 checkpoint.Call(1); 2220 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 2221 checkpoint.Call(2); 2222 } 2223 2224 // If for some reason the connect succeeds before the renderer sends us quota, 2225 // we shouldn't call ReadFrames() immediately. 2226 // TODO(ricea): Actually we should call ReadFrames() with a small limit so we 2227 // can still handle control frames. This should be done once we have any API to 2228 // expose quota to the lower levels. 2229 TEST_F(WebSocketChannelStreamTest, FlowControlLate) { 2230 Checkpoint checkpoint; 2231 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2232 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2233 { 2234 InSequence s; 2235 EXPECT_CALL(checkpoint, Call(1)); 2236 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2237 .WillOnce(Return(ERR_IO_PENDING)); 2238 EXPECT_CALL(checkpoint, Call(2)); 2239 } 2240 2241 set_stream(mock_stream_.Pass()); 2242 CreateChannelAndConnect(); 2243 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 2244 checkpoint.Call(1); 2245 channel_->SendFlowControl(kPlentyOfQuota); 2246 checkpoint.Call(2); 2247 } 2248 2249 // We should stop calling ReadFrames() when all quota is used. 2250 TEST_F(WebSocketChannelStreamTest, FlowControlStopsReadFrames) { 2251 static const InitFrame frames[] = { 2252 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; 2253 2254 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2255 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2256 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2257 .WillOnce(ReturnFrames(&frames)); 2258 2259 set_stream(mock_stream_.Pass()); 2260 CreateChannelAndConnect(); 2261 channel_->SendFlowControl(4); 2262 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 2263 } 2264 2265 // Providing extra quota causes ReadFrames() to be called again. 2266 TEST_F(WebSocketChannelStreamTest, FlowControlStartsWithMoreQuota) { 2267 static const InitFrame frames[] = { 2268 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; 2269 Checkpoint checkpoint; 2270 2271 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2272 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2273 { 2274 InSequence s; 2275 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2276 .WillOnce(ReturnFrames(&frames)); 2277 EXPECT_CALL(checkpoint, Call(1)); 2278 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2279 .WillOnce(Return(ERR_IO_PENDING)); 2280 } 2281 2282 set_stream(mock_stream_.Pass()); 2283 CreateChannelAndConnect(); 2284 channel_->SendFlowControl(4); 2285 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 2286 checkpoint.Call(1); 2287 channel_->SendFlowControl(4); 2288 } 2289 2290 // ReadFrames() isn't called again until all pending data has been passed to 2291 // the renderer. 2292 TEST_F(WebSocketChannelStreamTest, ReadFramesNotCalledUntilQuotaAvailable) { 2293 static const InitFrame frames[] = { 2294 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; 2295 Checkpoint checkpoint; 2296 2297 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2298 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2299 { 2300 InSequence s; 2301 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2302 .WillOnce(ReturnFrames(&frames)); 2303 EXPECT_CALL(checkpoint, Call(1)); 2304 EXPECT_CALL(checkpoint, Call(2)); 2305 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2306 .WillOnce(Return(ERR_IO_PENDING)); 2307 } 2308 2309 set_stream(mock_stream_.Pass()); 2310 CreateChannelAndConnect(); 2311 channel_->SendFlowControl(2); 2312 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 2313 checkpoint.Call(1); 2314 channel_->SendFlowControl(2); 2315 checkpoint.Call(2); 2316 channel_->SendFlowControl(2); 2317 } 2318 2319 // A message that needs to be split into frames to fit within quota should 2320 // maintain correct semantics. 2321 TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitSync) { 2322 scoped_ptr<ReadableFakeWebSocketStream> stream( 2323 new ReadableFakeWebSocketStream); 2324 static const InitFrame frames[] = { 2325 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; 2326 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2327 set_stream(stream.Pass()); 2328 { 2329 InSequence s; 2330 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2331 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2332 EXPECT_CALL( 2333 *event_interface_, 2334 OnDataFrame(false, WebSocketFrameHeader::kOpCodeText, AsVector("FO"))); 2335 EXPECT_CALL( 2336 *event_interface_, 2337 OnDataFrame( 2338 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector("U"))); 2339 EXPECT_CALL( 2340 *event_interface_, 2341 OnDataFrame( 2342 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("R"))); 2343 } 2344 2345 CreateChannelAndConnectWithQuota(2); 2346 channel_->SendFlowControl(1); 2347 channel_->SendFlowControl(1); 2348 } 2349 2350 // The code path for async messages is slightly different, so test it 2351 // separately. 2352 TEST_F(WebSocketChannelFlowControlTest, SingleFrameMessageSplitAsync) { 2353 scoped_ptr<ReadableFakeWebSocketStream> stream( 2354 new ReadableFakeWebSocketStream); 2355 static const InitFrame frames[] = { 2356 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "FOUR"}}; 2357 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 2358 set_stream(stream.Pass()); 2359 Checkpoint checkpoint; 2360 { 2361 InSequence s; 2362 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2363 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2364 EXPECT_CALL(checkpoint, Call(1)); 2365 EXPECT_CALL( 2366 *event_interface_, 2367 OnDataFrame(false, WebSocketFrameHeader::kOpCodeText, AsVector("FO"))); 2368 EXPECT_CALL(checkpoint, Call(2)); 2369 EXPECT_CALL( 2370 *event_interface_, 2371 OnDataFrame( 2372 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector("U"))); 2373 EXPECT_CALL(checkpoint, Call(3)); 2374 EXPECT_CALL( 2375 *event_interface_, 2376 OnDataFrame( 2377 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("R"))); 2378 } 2379 2380 CreateChannelAndConnectWithQuota(2); 2381 checkpoint.Call(1); 2382 base::MessageLoop::current()->RunUntilIdle(); 2383 checkpoint.Call(2); 2384 channel_->SendFlowControl(1); 2385 checkpoint.Call(3); 2386 channel_->SendFlowControl(1); 2387 } 2388 2389 // A message split into multiple frames which is further split due to quota 2390 // restrictions should stil be correct. 2391 // TODO(ricea): The message ends up split into more frames than are strictly 2392 // necessary. The complexity/performance tradeoffs here need further 2393 // examination. 2394 TEST_F(WebSocketChannelFlowControlTest, MultipleFrameSplit) { 2395 scoped_ptr<ReadableFakeWebSocketStream> stream( 2396 new ReadableFakeWebSocketStream); 2397 static const InitFrame frames[] = { 2398 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 2399 NOT_MASKED, "FIRST FRAME IS 25 BYTES. "}, 2400 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 2401 NOT_MASKED, "SECOND FRAME IS 26 BYTES. "}, 2402 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 2403 NOT_MASKED, "FINAL FRAME IS 24 BYTES."}}; 2404 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2405 set_stream(stream.Pass()); 2406 { 2407 InSequence s; 2408 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2409 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2410 EXPECT_CALL(*event_interface_, 2411 OnDataFrame(false, 2412 WebSocketFrameHeader::kOpCodeText, 2413 AsVector("FIRST FRAME IS"))); 2414 EXPECT_CALL(*event_interface_, 2415 OnDataFrame(false, 2416 WebSocketFrameHeader::kOpCodeContinuation, 2417 AsVector(" 25 BYTES. "))); 2418 EXPECT_CALL(*event_interface_, 2419 OnDataFrame(false, 2420 WebSocketFrameHeader::kOpCodeContinuation, 2421 AsVector("SECOND FRAME IS 26 BYTES. "))); 2422 EXPECT_CALL(*event_interface_, 2423 OnDataFrame(false, 2424 WebSocketFrameHeader::kOpCodeContinuation, 2425 AsVector("FINAL "))); 2426 EXPECT_CALL(*event_interface_, 2427 OnDataFrame(true, 2428 WebSocketFrameHeader::kOpCodeContinuation, 2429 AsVector("FRAME IS 24 BYTES."))); 2430 } 2431 CreateChannelAndConnectWithQuota(14); 2432 channel_->SendFlowControl(43); 2433 channel_->SendFlowControl(32); 2434 } 2435 2436 // An empty message handled when we are out of quota must not be delivered 2437 // out-of-order with respect to other messages. 2438 TEST_F(WebSocketChannelFlowControlTest, EmptyMessageNoQuota) { 2439 scoped_ptr<ReadableFakeWebSocketStream> stream( 2440 new ReadableFakeWebSocketStream); 2441 static const InitFrame frames[] = { 2442 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 2443 NOT_MASKED, "FIRST MESSAGE"}, 2444 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 2445 NOT_MASKED, NULL}, 2446 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 2447 NOT_MASKED, "THIRD MESSAGE"}}; 2448 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 2449 set_stream(stream.Pass()); 2450 { 2451 InSequence s; 2452 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2453 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2454 EXPECT_CALL(*event_interface_, 2455 OnDataFrame(false, 2456 WebSocketFrameHeader::kOpCodeText, 2457 AsVector("FIRST "))); 2458 EXPECT_CALL(*event_interface_, 2459 OnDataFrame(true, 2460 WebSocketFrameHeader::kOpCodeContinuation, 2461 AsVector("MESSAGE"))); 2462 EXPECT_CALL(*event_interface_, 2463 OnDataFrame(true, 2464 WebSocketFrameHeader::kOpCodeText, 2465 AsVector(""))); 2466 EXPECT_CALL(*event_interface_, 2467 OnDataFrame(true, 2468 WebSocketFrameHeader::kOpCodeText, 2469 AsVector("THIRD MESSAGE"))); 2470 } 2471 2472 CreateChannelAndConnectWithQuota(6); 2473 channel_->SendFlowControl(128); 2474 } 2475 2476 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". 2477 // WebSocketChannel actually only sets the mask bit in the header, it doesn't 2478 // perform masking itself (not all transports actually use masking). 2479 TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { 2480 static const InitFrame expected[] = { 2481 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 2482 MASKED, "NEEDS MASKING"}}; 2483 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2484 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2485 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2486 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2487 .WillOnce(Return(OK)); 2488 2489 CreateChannelAndConnectSuccessfully(); 2490 channel_->SendFrame( 2491 true, WebSocketFrameHeader::kOpCodeText, AsVector("NEEDS MASKING")); 2492 } 2493 2494 // RFC6455 5.5.1 "The application MUST NOT send any more data frames after 2495 // sending a Close frame." 2496 TEST_F(WebSocketChannelStreamTest, NothingIsSentAfterClose) { 2497 static const InitFrame expected[] = { 2498 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2499 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 2500 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2501 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2502 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2503 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2504 .WillOnce(Return(OK)); 2505 2506 CreateChannelAndConnectSuccessfully(); 2507 channel_->StartClosingHandshake(1000, "Success"); 2508 channel_->SendFrame( 2509 true, WebSocketFrameHeader::kOpCodeText, AsVector("SHOULD BE IGNORED")); 2510 } 2511 2512 // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously 2513 // send a Close frame, the endpoint MUST send a Close frame in response." 2514 TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { 2515 static const InitFrame frames[] = { 2516 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2517 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 2518 static const InitFrame expected[] = { 2519 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2520 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 2521 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2522 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2523 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2524 .WillOnce(ReturnFrames(&frames)) 2525 .WillRepeatedly(Return(ERR_IO_PENDING)); 2526 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2527 .WillOnce(Return(OK)); 2528 2529 CreateChannelAndConnectSuccessfully(); 2530 } 2531 2532 // The converse of the above case; after sending a Close frame, we should not 2533 // send another one. 2534 TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { 2535 static const InitFrame expected[] = { 2536 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2537 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 2538 static const InitFrame frames_init[] = { 2539 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2540 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 2541 2542 // We store the parameters that were passed to ReadFrames() so that we can 2543 // call them explicitly later. 2544 CompletionCallback read_callback; 2545 ScopedVector<WebSocketFrame>* frames = NULL; 2546 2547 // These are not interesting. 2548 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2549 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2550 2551 // Use a checkpoint to make the ordering of events clearer. 2552 Checkpoint checkpoint; 2553 { 2554 InSequence s; 2555 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2556 .WillOnce(DoAll(SaveArg<0>(&frames), 2557 SaveArg<1>(&read_callback), 2558 Return(ERR_IO_PENDING))); 2559 EXPECT_CALL(checkpoint, Call(1)); 2560 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2561 .WillOnce(Return(OK)); 2562 EXPECT_CALL(checkpoint, Call(2)); 2563 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2564 .WillOnce(Return(ERR_IO_PENDING)); 2565 EXPECT_CALL(checkpoint, Call(3)); 2566 // WriteFrames() must not be called again. GoogleMock will ensure that the 2567 // test fails if it is. 2568 } 2569 2570 CreateChannelAndConnectSuccessfully(); 2571 checkpoint.Call(1); 2572 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close"); 2573 checkpoint.Call(2); 2574 2575 *frames = CreateFrameVector(frames_init); 2576 read_callback.Run(OK); 2577 checkpoint.Call(3); 2578 } 2579 2580 // Invalid close status codes should not be sent on the network. 2581 TEST_F(WebSocketChannelStreamTest, InvalidCloseStatusCodeNotSent) { 2582 static const InitFrame expected[] = { 2583 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2584 MASKED, CLOSE_DATA(SERVER_ERROR, "")}}; 2585 2586 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2587 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2588 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2589 .WillOnce(Return(ERR_IO_PENDING)); 2590 2591 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); 2592 2593 CreateChannelAndConnectSuccessfully(); 2594 channel_->StartClosingHandshake(999, ""); 2595 } 2596 2597 // A Close frame with a reason longer than 123 bytes cannot be sent on the 2598 // network. 2599 TEST_F(WebSocketChannelStreamTest, LongCloseReasonNotSent) { 2600 static const InitFrame expected[] = { 2601 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2602 MASKED, CLOSE_DATA(SERVER_ERROR, "")}}; 2603 2604 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2605 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2606 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2607 .WillOnce(Return(ERR_IO_PENDING)); 2608 2609 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); 2610 2611 CreateChannelAndConnectSuccessfully(); 2612 channel_->StartClosingHandshake(1000, std::string(124, 'A')); 2613 } 2614 2615 // We generate code 1005, kWebSocketErrorNoStatusReceived, when there is no 2616 // status in the Close message from the other side. Code 1005 is not allowed to 2617 // appear on the wire, so we should not echo it back. See test 2618 // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is 2619 // correctly generated internally. 2620 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { 2621 static const InitFrame frames[] = { 2622 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; 2623 static const InitFrame expected[] = { 2624 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, ""}}; 2625 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2626 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2627 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2628 .WillOnce(ReturnFrames(&frames)) 2629 .WillRepeatedly(Return(ERR_IO_PENDING)); 2630 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2631 .WillOnce(Return(OK)); 2632 2633 CreateChannelAndConnectSuccessfully(); 2634 } 2635 2636 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoedNull) { 2637 static const InitFrame frames[] = { 2638 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, NULL}}; 2639 static const InitFrame expected[] = { 2640 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, ""}}; 2641 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2642 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2643 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2644 .WillOnce(ReturnFrames(&frames)) 2645 .WillRepeatedly(Return(ERR_IO_PENDING)); 2646 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2647 .WillOnce(Return(OK)); 2648 2649 CreateChannelAndConnectSuccessfully(); 2650 } 2651 2652 // Receiving an invalid UTF-8 payload in a Close frame causes us to fail the 2653 // connection. 2654 TEST_F(WebSocketChannelStreamTest, CloseFrameInvalidUtf8) { 2655 static const InitFrame frames[] = { 2656 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2657 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "\xFF")}}; 2658 static const InitFrame expected[] = { 2659 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2660 MASKED, CLOSE_DATA(PROTOCOL_ERROR, "Invalid UTF-8 in Close frame")}}; 2661 2662 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2663 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2664 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2665 .WillOnce(ReturnFrames(&frames)) 2666 .WillRepeatedly(Return(ERR_IO_PENDING)); 2667 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2668 .WillOnce(Return(OK)); 2669 EXPECT_CALL(*mock_stream_, Close()); 2670 2671 CreateChannelAndConnectSuccessfully(); 2672 } 2673 2674 // RFC6455 5.5.2 "Upon receipt of a Ping frame, an endpoint MUST send a Pong 2675 // frame in response" 2676 // 5.5.3 "A Pong frame sent in response to a Ping frame must have identical 2677 // "Application data" as found in the message body of the Ping frame being 2678 // replied to." 2679 TEST_F(WebSocketChannelStreamTest, PingRepliedWithPong) { 2680 static const InitFrame frames[] = { 2681 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, 2682 NOT_MASKED, "Application data"}}; 2683 static const InitFrame expected[] = { 2684 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, 2685 MASKED, "Application data"}}; 2686 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2687 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2688 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2689 .WillOnce(ReturnFrames(&frames)) 2690 .WillRepeatedly(Return(ERR_IO_PENDING)); 2691 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2692 .WillOnce(Return(OK)); 2693 2694 CreateChannelAndConnectSuccessfully(); 2695 } 2696 2697 // A ping with a NULL payload should be responded to with a Pong with a NULL 2698 // payload. 2699 TEST_F(WebSocketChannelStreamTest, NullPingRepliedWithNullPong) { 2700 static const InitFrame frames[] = { 2701 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, NULL}}; 2702 static const InitFrame expected[] = { 2703 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, MASKED, NULL}}; 2704 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2705 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2706 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2707 .WillOnce(ReturnFrames(&frames)) 2708 .WillRepeatedly(Return(ERR_IO_PENDING)); 2709 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2710 .WillOnce(Return(OK)); 2711 2712 CreateChannelAndConnectSuccessfully(); 2713 } 2714 2715 TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) { 2716 static const InitFrame frames[] = { 2717 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, 2718 NOT_MASKED, "Application data"}}; 2719 static const InitFrame expected1[] = { 2720 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; 2721 static const InitFrame expected2[] = { 2722 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, 2723 MASKED, "Application data"}}; 2724 static const InitFrame expected3[] = { 2725 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 2726 MASKED, "World"}}; 2727 ScopedVector<WebSocketFrame>* read_frames; 2728 CompletionCallback read_callback; 2729 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2730 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2731 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2732 .WillOnce(DoAll(SaveArg<0>(&read_frames), 2733 SaveArg<1>(&read_callback), 2734 Return(ERR_IO_PENDING))) 2735 .WillRepeatedly(Return(ERR_IO_PENDING)); 2736 { 2737 InSequence s; 2738 2739 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) 2740 .WillOnce(Return(OK)); 2741 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) 2742 .WillOnce(Return(OK)); 2743 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected3), _)) 2744 .WillOnce(Return(OK)); 2745 } 2746 2747 CreateChannelAndConnectSuccessfully(); 2748 channel_->SendFrame( 2749 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); 2750 *read_frames = CreateFrameVector(frames); 2751 read_callback.Run(OK); 2752 channel_->SendFrame( 2753 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("World")); 2754 } 2755 2756 // WriteFrames() may not be called until the previous write has completed. 2757 // WebSocketChannel must buffer writes that happen in the meantime. 2758 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { 2759 static const InitFrame expected1[] = { 2760 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; 2761 static const InitFrame expected2[] = { 2762 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; 2763 CompletionCallback write_callback; 2764 Checkpoint checkpoint; 2765 2766 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2767 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2768 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2769 { 2770 InSequence s; 2771 EXPECT_CALL(checkpoint, Call(1)); 2772 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) 2773 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); 2774 EXPECT_CALL(checkpoint, Call(2)); 2775 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) 2776 .WillOnce(Return(ERR_IO_PENDING)); 2777 EXPECT_CALL(checkpoint, Call(3)); 2778 } 2779 2780 CreateChannelAndConnectSuccessfully(); 2781 checkpoint.Call(1); 2782 channel_->SendFrame( 2783 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); 2784 channel_->SendFrame( 2785 true, WebSocketFrameHeader::kOpCodeText, AsVector("World")); 2786 checkpoint.Call(2); 2787 write_callback.Run(OK); 2788 checkpoint.Call(3); 2789 } 2790 2791 // WebSocketChannel must buffer frames while it is waiting for a write to 2792 // complete, and then send them in a single batch. The batching behaviour is 2793 // important to get good throughput in the "many small messages" case. 2794 TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) { 2795 static const char input_letters[] = "Hello"; 2796 static const InitFrame expected1[] = { 2797 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "H"}}; 2798 static const InitFrame expected2[] = { 2799 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "e"}, 2800 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"}, 2801 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"}, 2802 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "o"}}; 2803 CompletionCallback write_callback; 2804 2805 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2806 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2807 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2808 { 2809 InSequence s; 2810 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) 2811 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); 2812 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) 2813 .WillOnce(Return(ERR_IO_PENDING)); 2814 } 2815 2816 CreateChannelAndConnectSuccessfully(); 2817 for (size_t i = 0; i < strlen(input_letters); ++i) { 2818 channel_->SendFrame(true, 2819 WebSocketFrameHeader::kOpCodeText, 2820 std::vector<char>(1, input_letters[i])); 2821 } 2822 write_callback.Run(OK); 2823 } 2824 2825 // When the renderer sends more on a channel than it has quota for, we send the 2826 // remote server a kWebSocketErrorGoingAway error code. 2827 TEST_F(WebSocketChannelStreamTest, SendGoingAwayOnRendererQuotaExceeded) { 2828 static const InitFrame expected[] = { 2829 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2830 MASKED, CLOSE_DATA(GOING_AWAY, "")}}; 2831 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2832 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2833 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2834 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2835 .WillOnce(Return(OK)); 2836 EXPECT_CALL(*mock_stream_, Close()); 2837 2838 CreateChannelAndConnectSuccessfully(); 2839 channel_->SendFrame(true, 2840 WebSocketFrameHeader::kOpCodeText, 2841 std::vector<char>(kDefaultInitialQuota + 1, 'C')); 2842 } 2843 2844 // For convenience, most of these tests use Text frames. However, the WebSocket 2845 // protocol also has Binary frames and those need to be 8-bit clean. For the 2846 // sake of completeness, this test verifies that they are. 2847 TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) { 2848 ScopedVector<WebSocketFrame>* frames = NULL; 2849 2850 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2851 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 2852 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2853 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) 2854 .WillOnce(DoAll(SaveArg<0>(&frames), Return(ERR_IO_PENDING))); 2855 2856 CreateChannelAndConnectSuccessfully(); 2857 channel_->SendFrame( 2858 true, 2859 WebSocketFrameHeader::kOpCodeBinary, 2860 std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize)); 2861 ASSERT_TRUE(frames != NULL); 2862 ASSERT_EQ(1U, frames->size()); 2863 const WebSocketFrame* out_frame = (*frames)[0]; 2864 EXPECT_EQ(kBinaryBlobSize, out_frame->header.payload_length); 2865 ASSERT_TRUE(out_frame->data.get()); 2866 EXPECT_EQ(0, memcmp(kBinaryBlob, out_frame->data->data(), kBinaryBlobSize)); 2867 } 2868 2869 // Test the read path for 8-bit cleanliness as well. 2870 TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) { 2871 scoped_ptr<WebSocketFrame> frame( 2872 new WebSocketFrame(WebSocketFrameHeader::kOpCodeBinary)); 2873 WebSocketFrameHeader& frame_header = frame->header; 2874 frame_header.final = true; 2875 frame_header.payload_length = kBinaryBlobSize; 2876 frame->data = new IOBuffer(kBinaryBlobSize); 2877 memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize); 2878 ScopedVector<WebSocketFrame> frames; 2879 frames.push_back(frame.release()); 2880 scoped_ptr<ReadableFakeWebSocketStream> stream( 2881 new ReadableFakeWebSocketStream); 2882 stream->PrepareRawReadFrames( 2883 ReadableFakeWebSocketStream::SYNC, OK, frames.Pass()); 2884 set_stream(stream.Pass()); 2885 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 2886 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2887 EXPECT_CALL(*event_interface_, 2888 OnDataFrame(true, 2889 WebSocketFrameHeader::kOpCodeBinary, 2890 std::vector<char>(kBinaryBlob, 2891 kBinaryBlob + kBinaryBlobSize))); 2892 2893 CreateChannelAndConnectSuccessfully(); 2894 } 2895 2896 // Invalid UTF-8 is not permitted in Text frames. 2897 TEST_F(WebSocketChannelSendUtf8Test, InvalidUtf8Rejected) { 2898 EXPECT_CALL( 2899 *event_interface_, 2900 OnFailChannel("Browser sent a text frame containing invalid UTF-8")); 2901 2902 CreateChannelAndConnectSuccessfully(); 2903 2904 channel_->SendFrame( 2905 true, WebSocketFrameHeader::kOpCodeText, AsVector("\xff")); 2906 } 2907 2908 // A Text message cannot end with a partial UTF-8 character. 2909 TEST_F(WebSocketChannelSendUtf8Test, IncompleteCharacterInFinalFrame) { 2910 EXPECT_CALL( 2911 *event_interface_, 2912 OnFailChannel("Browser sent a text frame containing invalid UTF-8")); 2913 2914 CreateChannelAndConnectSuccessfully(); 2915 2916 channel_->SendFrame( 2917 true, WebSocketFrameHeader::kOpCodeText, AsVector("\xc2")); 2918 } 2919 2920 // A non-final Text frame may end with a partial UTF-8 character (compare to 2921 // previous test). 2922 TEST_F(WebSocketChannelSendUtf8Test, IncompleteCharacterInNonFinalFrame) { 2923 CreateChannelAndConnectSuccessfully(); 2924 2925 channel_->SendFrame( 2926 false, WebSocketFrameHeader::kOpCodeText, AsVector("\xc2")); 2927 } 2928 2929 // UTF-8 parsing context must be retained between frames. 2930 TEST_F(WebSocketChannelSendUtf8Test, ValidCharacterSplitBetweenFrames) { 2931 CreateChannelAndConnectSuccessfully(); 2932 2933 channel_->SendFrame( 2934 false, WebSocketFrameHeader::kOpCodeText, AsVector("\xf1")); 2935 channel_->SendFrame(true, 2936 WebSocketFrameHeader::kOpCodeContinuation, 2937 AsVector("\x80\xa0\xbf")); 2938 } 2939 2940 // Similarly, an invalid character should be detected even if split. 2941 TEST_F(WebSocketChannelSendUtf8Test, InvalidCharacterSplit) { 2942 EXPECT_CALL( 2943 *event_interface_, 2944 OnFailChannel("Browser sent a text frame containing invalid UTF-8")); 2945 2946 CreateChannelAndConnectSuccessfully(); 2947 2948 channel_->SendFrame( 2949 false, WebSocketFrameHeader::kOpCodeText, AsVector("\xe1")); 2950 channel_->SendFrame(true, 2951 WebSocketFrameHeader::kOpCodeContinuation, 2952 AsVector("\x80\xa0\xbf")); 2953 } 2954 2955 // An invalid character must be detected in continuation frames. 2956 TEST_F(WebSocketChannelSendUtf8Test, InvalidByteInContinuation) { 2957 EXPECT_CALL( 2958 *event_interface_, 2959 OnFailChannel("Browser sent a text frame containing invalid UTF-8")); 2960 2961 CreateChannelAndConnectSuccessfully(); 2962 2963 channel_->SendFrame( 2964 false, WebSocketFrameHeader::kOpCodeText, AsVector("foo")); 2965 channel_->SendFrame( 2966 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector("bar")); 2967 channel_->SendFrame( 2968 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("\xff")); 2969 } 2970 2971 // However, continuation frames of a Binary frame will not be tested for UTF-8 2972 // validity. 2973 TEST_F(WebSocketChannelSendUtf8Test, BinaryContinuationNotChecked) { 2974 CreateChannelAndConnectSuccessfully(); 2975 2976 channel_->SendFrame( 2977 false, WebSocketFrameHeader::kOpCodeBinary, AsVector("foo")); 2978 channel_->SendFrame( 2979 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector("bar")); 2980 channel_->SendFrame( 2981 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("\xff")); 2982 } 2983 2984 // Multiple text messages can be validated without the validation state getting 2985 // confused. 2986 TEST_F(WebSocketChannelSendUtf8Test, ValidateMultipleTextMessages) { 2987 CreateChannelAndConnectSuccessfully(); 2988 2989 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("foo")); 2990 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("bar")); 2991 } 2992 2993 // UTF-8 validation is enforced on received Text frames. 2994 TEST_F(WebSocketChannelEventInterfaceTest, ReceivedInvalidUtf8) { 2995 scoped_ptr<ReadableFakeWebSocketStream> stream( 2996 new ReadableFakeWebSocketStream); 2997 static const InitFrame frames[] = { 2998 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xff"}}; 2999 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 3000 set_stream(stream.Pass()); 3001 3002 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 3003 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); 3004 EXPECT_CALL(*event_interface_, 3005 OnFailChannel("Could not decode a text frame as UTF-8.")); 3006 3007 CreateChannelAndConnectSuccessfully(); 3008 base::MessageLoop::current()->RunUntilIdle(); 3009 } 3010 3011 // Invalid UTF-8 is not sent over the network. 3012 TEST_F(WebSocketChannelStreamTest, InvalidUtf8TextFrameNotSent) { 3013 static const InitFrame expected[] = {{FINAL_FRAME, 3014 WebSocketFrameHeader::kOpCodeClose, 3015 MASKED, CLOSE_DATA(GOING_AWAY, "")}}; 3016 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 3017 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 3018 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3019 .WillRepeatedly(Return(ERR_IO_PENDING)); 3020 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3021 .WillOnce(Return(OK)); 3022 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3023 3024 CreateChannelAndConnectSuccessfully(); 3025 3026 channel_->SendFrame( 3027 true, WebSocketFrameHeader::kOpCodeText, AsVector("\xff")); 3028 } 3029 3030 // The rest of the tests for receiving invalid UTF-8 test the communication with 3031 // the server. Since there is only one code path, it would be redundant to 3032 // perform the same tests on the EventInterface as well. 3033 3034 // If invalid UTF-8 is received in a Text frame, the connection is failed. 3035 TEST_F(WebSocketChannelReceiveUtf8Test, InvalidTextFrameRejected) { 3036 static const InitFrame frames[] = { 3037 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xff"}}; 3038 static const InitFrame expected[] = { 3039 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 3040 CLOSE_DATA(PROTOCOL_ERROR, "Invalid UTF-8 in text frame")}}; 3041 { 3042 InSequence s; 3043 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3044 .WillOnce(ReturnFrames(&frames)) 3045 .WillRepeatedly(Return(ERR_IO_PENDING)); 3046 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3047 .WillOnce(Return(OK)); 3048 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3049 } 3050 3051 CreateChannelAndConnectSuccessfully(); 3052 } 3053 3054 // A received Text message is not permitted to end with a partial UTF-8 3055 // character. 3056 TEST_F(WebSocketChannelReceiveUtf8Test, IncompleteCharacterReceived) { 3057 static const InitFrame frames[] = { 3058 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xc2"}}; 3059 static const InitFrame expected[] = { 3060 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 3061 CLOSE_DATA(PROTOCOL_ERROR, "Invalid UTF-8 in text frame")}}; 3062 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3063 .WillOnce(ReturnFrames(&frames)) 3064 .WillRepeatedly(Return(ERR_IO_PENDING)); 3065 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3066 .WillOnce(Return(OK)); 3067 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3068 3069 CreateChannelAndConnectSuccessfully(); 3070 } 3071 3072 // However, a non-final Text frame may end with a partial UTF-8 character. 3073 TEST_F(WebSocketChannelReceiveUtf8Test, IncompleteCharacterIncompleteMessage) { 3074 static const InitFrame frames[] = { 3075 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xc2"}}; 3076 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3077 .WillOnce(ReturnFrames(&frames)) 3078 .WillRepeatedly(Return(ERR_IO_PENDING)); 3079 3080 CreateChannelAndConnectSuccessfully(); 3081 } 3082 3083 // However, it will become an error if it is followed by an empty final frame. 3084 TEST_F(WebSocketChannelReceiveUtf8Test, TricksyIncompleteCharacter) { 3085 static const InitFrame frames[] = { 3086 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xc2"}, 3087 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, ""}}; 3088 static const InitFrame expected[] = { 3089 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 3090 CLOSE_DATA(PROTOCOL_ERROR, "Invalid UTF-8 in text frame")}}; 3091 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3092 .WillOnce(ReturnFrames(&frames)) 3093 .WillRepeatedly(Return(ERR_IO_PENDING)); 3094 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3095 .WillOnce(Return(OK)); 3096 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3097 3098 CreateChannelAndConnectSuccessfully(); 3099 } 3100 3101 // UTF-8 parsing context must be retained between received frames of the same 3102 // message. 3103 TEST_F(WebSocketChannelReceiveUtf8Test, ReceivedParsingContextRetained) { 3104 static const InitFrame frames[] = { 3105 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xf1"}, 3106 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3107 NOT_MASKED, "\x80\xa0\xbf"}}; 3108 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3109 .WillOnce(ReturnFrames(&frames)) 3110 .WillRepeatedly(Return(ERR_IO_PENDING)); 3111 3112 CreateChannelAndConnectSuccessfully(); 3113 } 3114 3115 // An invalid character must be detected even if split between frames. 3116 TEST_F(WebSocketChannelReceiveUtf8Test, SplitInvalidCharacterReceived) { 3117 static const InitFrame frames[] = { 3118 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "\xe1"}, 3119 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3120 NOT_MASKED, "\x80\xa0\xbf"}}; 3121 static const InitFrame expected[] = { 3122 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 3123 CLOSE_DATA(PROTOCOL_ERROR, "Invalid UTF-8 in text frame")}}; 3124 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3125 .WillOnce(ReturnFrames(&frames)) 3126 .WillRepeatedly(Return(ERR_IO_PENDING)); 3127 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3128 .WillOnce(Return(OK)); 3129 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3130 3131 CreateChannelAndConnectSuccessfully(); 3132 } 3133 3134 // An invalid character received in a continuation frame must be detected. 3135 TEST_F(WebSocketChannelReceiveUtf8Test, InvalidReceivedIncontinuation) { 3136 static const InitFrame frames[] = { 3137 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "foo"}, 3138 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3139 NOT_MASKED, "bar"}, 3140 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3141 NOT_MASKED, "\xff"}}; 3142 static const InitFrame expected[] = { 3143 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, 3144 CLOSE_DATA(PROTOCOL_ERROR, "Invalid UTF-8 in text frame")}}; 3145 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3146 .WillOnce(ReturnFrames(&frames)) 3147 .WillRepeatedly(Return(ERR_IO_PENDING)); 3148 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3149 .WillOnce(Return(OK)); 3150 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3151 3152 CreateChannelAndConnectSuccessfully(); 3153 } 3154 3155 // Continuations of binary frames must not be tested for UTF-8 validity. 3156 TEST_F(WebSocketChannelReceiveUtf8Test, ReceivedBinaryNotUtf8Tested) { 3157 static const InitFrame frames[] = { 3158 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeBinary, NOT_MASKED, "foo"}, 3159 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3160 NOT_MASKED, "bar"}, 3161 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3162 NOT_MASKED, "\xff"}}; 3163 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3164 .WillOnce(ReturnFrames(&frames)) 3165 .WillRepeatedly(Return(ERR_IO_PENDING)); 3166 3167 CreateChannelAndConnectSuccessfully(); 3168 } 3169 3170 // Multiple Text messages can be validated. 3171 TEST_F(WebSocketChannelReceiveUtf8Test, ValidateMultipleReceived) { 3172 static const InitFrame frames[] = { 3173 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "foo"}, 3174 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "bar"}}; 3175 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3176 .WillOnce(ReturnFrames(&frames)) 3177 .WillRepeatedly(Return(ERR_IO_PENDING)); 3178 3179 CreateChannelAndConnectSuccessfully(); 3180 } 3181 3182 // A new data message cannot start in the middle of another data message. 3183 TEST_F(WebSocketChannelEventInterfaceTest, BogusContinuation) { 3184 scoped_ptr<ReadableFakeWebSocketStream> stream( 3185 new ReadableFakeWebSocketStream); 3186 static const InitFrame frames[] = { 3187 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeBinary, 3188 NOT_MASKED, "frame1"}, 3189 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 3190 NOT_MASKED, "frame2"}}; 3191 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 3192 set_stream(stream.Pass()); 3193 3194 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 3195 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); 3196 EXPECT_CALL( 3197 *event_interface_, 3198 OnDataFrame( 3199 false, WebSocketFrameHeader::kOpCodeBinary, AsVector("frame1"))); 3200 EXPECT_CALL( 3201 *event_interface_, 3202 OnFailChannel( 3203 "Received start of new message but previous message is unfinished.")); 3204 3205 CreateChannelAndConnectSuccessfully(); 3206 } 3207 3208 // A new message cannot start with a Continuation frame. 3209 TEST_F(WebSocketChannelEventInterfaceTest, MessageStartingWithContinuation) { 3210 scoped_ptr<ReadableFakeWebSocketStream> stream( 3211 new ReadableFakeWebSocketStream); 3212 static const InitFrame frames[] = { 3213 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3214 NOT_MASKED, "continuation"}}; 3215 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 3216 set_stream(stream.Pass()); 3217 3218 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 3219 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); 3220 EXPECT_CALL(*event_interface_, 3221 OnFailChannel("Received unexpected continuation frame.")); 3222 3223 CreateChannelAndConnectSuccessfully(); 3224 } 3225 3226 // A frame passed to the renderer must be either non-empty or have the final bit 3227 // set. 3228 TEST_F(WebSocketChannelEventInterfaceTest, DataFramesNonEmptyOrFinal) { 3229 scoped_ptr<ReadableFakeWebSocketStream> stream( 3230 new ReadableFakeWebSocketStream); 3231 static const InitFrame frames[] = { 3232 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, ""}, 3233 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 3234 NOT_MASKED, ""}, 3235 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, NOT_MASKED, ""}}; 3236 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 3237 set_stream(stream.Pass()); 3238 3239 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _, _)); 3240 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); 3241 EXPECT_CALL( 3242 *event_interface_, 3243 OnDataFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector(""))); 3244 3245 CreateChannelAndConnectSuccessfully(); 3246 } 3247 3248 // Calls to OnSSLCertificateError() must be passed through to the event 3249 // interface with the correct URL attached. 3250 TEST_F(WebSocketChannelEventInterfaceTest, OnSSLCertificateErrorCalled) { 3251 const GURL wss_url("wss://example.com/sslerror"); 3252 connect_data_.socket_url = wss_url; 3253 const SSLInfo ssl_info; 3254 const bool fatal = true; 3255 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> fake_callbacks( 3256 new FakeSSLErrorCallbacks); 3257 3258 EXPECT_CALL(*event_interface_, 3259 OnSSLCertificateErrorCalled(NotNull(), wss_url, _, fatal)); 3260 3261 CreateChannelAndConnect(); 3262 connect_data_.creator.connect_delegate->OnSSLCertificateError( 3263 fake_callbacks.Pass(), ssl_info, fatal); 3264 } 3265 3266 // If we receive another frame after Close, it is not valid. It is not 3267 // completely clear what behaviour is required from the standard in this case, 3268 // but the current implementation fails the connection. Since a Close has 3269 // already been sent, this just means closing the connection. 3270 TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { 3271 static const InitFrame frames[] = { 3272 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3273 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, 3274 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, 3275 NOT_MASKED, "Ping body"}}; 3276 static const InitFrame expected[] = { 3277 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3278 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 3279 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 3280 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 3281 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3282 .WillOnce(ReturnFrames(&frames)) 3283 .WillRepeatedly(Return(ERR_IO_PENDING)); 3284 { 3285 // We only need to verify the relative order of WriteFrames() and 3286 // Close(). The current implementation calls WriteFrames() for the Close 3287 // frame before calling ReadFrames() again, but that is an implementation 3288 // detail and better not to consider required behaviour. 3289 InSequence s; 3290 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3291 .WillOnce(Return(OK)); 3292 EXPECT_CALL(*mock_stream_, Close()).Times(1); 3293 } 3294 3295 CreateChannelAndConnectSuccessfully(); 3296 } 3297 3298 // A protocol error from the remote server should result in a close frame with 3299 // status 1002, followed by the connection closing. 3300 TEST_F(WebSocketChannelStreamTest, ProtocolError) { 3301 static const InitFrame expected[] = { 3302 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3303 MASKED, CLOSE_DATA(PROTOCOL_ERROR, "WebSocket Protocol Error")}}; 3304 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 3305 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 3306 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3307 .WillOnce(Return(ERR_WS_PROTOCOL_ERROR)); 3308 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3309 .WillOnce(Return(OK)); 3310 EXPECT_CALL(*mock_stream_, Close()); 3311 3312 CreateChannelAndConnectSuccessfully(); 3313 } 3314 3315 // Set the closing handshake timeout to a very tiny value before connecting. 3316 class WebSocketChannelStreamTimeoutTest : public WebSocketChannelStreamTest { 3317 protected: 3318 WebSocketChannelStreamTimeoutTest() {} 3319 3320 virtual void CreateChannelAndConnectSuccessfully() OVERRIDE { 3321 set_stream(mock_stream_.Pass()); 3322 CreateChannelAndConnect(); 3323 channel_->SendFlowControl(kPlentyOfQuota); 3324 channel_->SetClosingHandshakeTimeoutForTesting( 3325 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); 3326 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 3327 } 3328 }; 3329 3330 // In this case the server initiates the closing handshake with a Close 3331 // message. WebSocketChannel responds with a matching Close message, and waits 3332 // for the server to close the TCP/IP connection. The server never closes the 3333 // connection, so the closing handshake times out and WebSocketChannel closes 3334 // the connection itself. 3335 TEST_F(WebSocketChannelStreamTimeoutTest, ServerInitiatedCloseTimesOut) { 3336 static const InitFrame frames[] = { 3337 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3338 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 3339 static const InitFrame expected[] = { 3340 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3341 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 3342 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 3343 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 3344 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3345 .WillOnce(ReturnFrames(&frames)) 3346 .WillRepeatedly(Return(ERR_IO_PENDING)); 3347 Checkpoint checkpoint; 3348 TestClosure completion; 3349 { 3350 InSequence s; 3351 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3352 .WillOnce(Return(OK)); 3353 EXPECT_CALL(checkpoint, Call(1)); 3354 EXPECT_CALL(*mock_stream_, Close()) 3355 .WillOnce(InvokeClosure(completion.closure())); 3356 } 3357 3358 CreateChannelAndConnectSuccessfully(); 3359 checkpoint.Call(1); 3360 completion.WaitForResult(); 3361 } 3362 3363 // In this case the client initiates the closing handshake by sending a Close 3364 // message. WebSocketChannel waits for a Close message in response from the 3365 // server. The server never responds to the Close message, so the closing 3366 // handshake times out and WebSocketChannel closes the connection. 3367 TEST_F(WebSocketChannelStreamTimeoutTest, ClientInitiatedCloseTimesOut) { 3368 static const InitFrame expected[] = { 3369 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3370 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 3371 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 3372 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 3373 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3374 .WillRepeatedly(Return(ERR_IO_PENDING)); 3375 TestClosure completion; 3376 { 3377 InSequence s; 3378 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3379 .WillOnce(Return(OK)); 3380 EXPECT_CALL(*mock_stream_, Close()) 3381 .WillOnce(InvokeClosure(completion.closure())); 3382 } 3383 3384 CreateChannelAndConnectSuccessfully(); 3385 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); 3386 completion.WaitForResult(); 3387 } 3388 3389 // In this case the client initiates the closing handshake and the server 3390 // responds with a matching Close message. WebSocketChannel waits for the server 3391 // to close the TCP/IP connection, but it never does. The closing handshake 3392 // times out and WebSocketChannel closes the connection. 3393 TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) { 3394 static const InitFrame expected[] = { 3395 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3396 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 3397 static const InitFrame frames[] = { 3398 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 3399 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 3400 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 3401 EXPECT_CALL(*mock_stream_, GetExtensions()).Times(AnyNumber()); 3402 TestClosure completion; 3403 ScopedVector<WebSocketFrame>* read_frames = NULL; 3404 CompletionCallback read_callback; 3405 { 3406 InSequence s; 3407 // Copy the arguments to ReadFrames so that the test can call the callback 3408 // after it has send the close message. 3409 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3410 .WillOnce(DoAll(SaveArg<0>(&read_frames), 3411 SaveArg<1>(&read_callback), 3412 Return(ERR_IO_PENDING))); 3413 // The first real event that happens is the client sending the Close 3414 // message. 3415 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 3416 .WillOnce(Return(OK)); 3417 // The |read_frames| callback is called (from this test case) at this 3418 // point. ReadFrames is called again by WebSocketChannel, waiting for 3419 // ERR_CONNECTION_CLOSED. 3420 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 3421 .WillOnce(Return(ERR_IO_PENDING)); 3422 // The timeout happens and so WebSocketChannel closes the stream. 3423 EXPECT_CALL(*mock_stream_, Close()) 3424 .WillOnce(InvokeClosure(completion.closure())); 3425 } 3426 3427 CreateChannelAndConnectSuccessfully(); 3428 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); 3429 ASSERT_TRUE(read_frames); 3430 // Provide the "Close" message from the server. 3431 *read_frames = CreateFrameVector(frames); 3432 read_callback.Run(OK); 3433 completion.WaitForResult(); 3434 } 3435 3436 } // namespace 3437 } // namespace net 3438