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 <string.h> 8 9 #include <iostream> 10 #include <string> 11 #include <vector> 12 13 #include "base/bind.h" 14 #include "base/bind_helpers.h" 15 #include "base/callback.h" 16 #include "base/location.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_vector.h" 19 #include "base/memory/weak_ptr.h" 20 #include "base/message_loop/message_loop.h" 21 #include "base/safe_numerics.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/url_request/url_request_context.h" 26 #include "net/websockets/websocket_errors.h" 27 #include "net/websockets/websocket_event_interface.h" 28 #include "net/websockets/websocket_mux.h" 29 #include "testing/gmock/include/gmock/gmock.h" 30 #include "testing/gtest/include/gtest/gtest.h" 31 #include "url/gurl.h" 32 33 // Hacky macros to construct the body of a Close message from a code and a 34 // string, while ensuring the result is a compile-time constant string. 35 // Use like CLOSE_DATA(NORMAL_CLOSURE, "Explanation String") 36 #define CLOSE_DATA(code, string) WEBSOCKET_CLOSE_CODE_AS_STRING_##code string 37 #define WEBSOCKET_CLOSE_CODE_AS_STRING_NORMAL_CLOSURE "\x03\xe8" 38 #define WEBSOCKET_CLOSE_CODE_AS_STRING_GOING_AWAY "\x03\xe9" 39 #define WEBSOCKET_CLOSE_CODE_AS_STRING_PROTOCOL_ERROR "\x03\xea" 40 #define WEBSOCKET_CLOSE_CODE_AS_STRING_SERVER_ERROR "\x03\xf3" 41 42 namespace net { 43 44 // Printing helpers to allow GoogleMock to print frames. These are explicitly 45 // designed to look like the static initialisation format we use in these 46 // tests. They have to live in the net namespace in order to be found by 47 // GoogleMock; a nested anonymous namespace will not work. 48 49 std::ostream& operator<<(std::ostream& os, const WebSocketFrameHeader& header) { 50 return os << (header.final ? "FINAL_FRAME" : "NOT_FINAL_FRAME") << ", " 51 << header.opcode << ", " 52 << (header.masked ? "MASKED" : "NOT_MASKED"); 53 } 54 55 std::ostream& operator<<(std::ostream& os, const WebSocketFrame& frame) { 56 os << "{" << frame.header << ", "; 57 if (frame.data) { 58 return os << "\"" << base::StringPiece(frame.data->data(), 59 frame.header.payload_length) 60 << "\"}"; 61 } 62 return os << "NULL}"; 63 } 64 65 std::ostream& operator<<(std::ostream& os, 66 const ScopedVector<WebSocketFrame>& vector) { 67 os << "{"; 68 bool first = true; 69 for (ScopedVector<WebSocketFrame>::const_iterator it = vector.begin(); 70 it != vector.end(); 71 ++it) { 72 if (!first) { 73 os << ",\n"; 74 } else { 75 first = false; 76 } 77 os << **it; 78 } 79 return os << "}"; 80 } 81 82 std::ostream& operator<<(std::ostream& os, 83 const ScopedVector<WebSocketFrame>* vector) { 84 return os << '&' << *vector; 85 } 86 87 namespace { 88 89 using ::base::TimeDelta; 90 91 using ::testing::AnyNumber; 92 using ::testing::DefaultValue; 93 using ::testing::InSequence; 94 using ::testing::MockFunction; 95 using ::testing::Return; 96 using ::testing::SaveArg; 97 using ::testing::StrictMock; 98 using ::testing::_; 99 100 // A selection of characters that have traditionally been mangled in some 101 // environment or other, for testing 8-bit cleanliness. 102 const char kBinaryBlob[] = {'\n', '\r', // BACKWARDS CRNL 103 '\0', // nul 104 '\x7F', // DEL 105 '\x80', '\xFF', // NOT VALID UTF-8 106 '\x1A', // Control-Z, EOF on DOS 107 '\x03', // Control-C 108 '\x04', // EOT, special for Unix terms 109 '\x1B', // ESC, often special 110 '\b', // backspace 111 '\'', // single-quote, special in PHP 112 }; 113 const size_t kBinaryBlobSize = arraysize(kBinaryBlob); 114 115 // The amount of quota a new connection gets by default. 116 // TODO(ricea): If kDefaultSendQuotaHighWaterMark changes, then this value will 117 // need to be updated. 118 const size_t kDefaultInitialQuota = 1 << 17; 119 // The amount of bytes we need to send after the initial connection to trigger a 120 // quota refresh. TODO(ricea): Change this if kDefaultSendQuotaHighWaterMark or 121 // kDefaultSendQuotaLowWaterMark change. 122 const size_t kDefaultQuotaRefreshTrigger = (1 << 16) + 1; 123 124 // TestTimeouts::tiny_timeout() is 100ms! I could run halfway around the world 125 // in that time! I would like my tests to run a bit quicker. 126 const int kVeryTinyTimeoutMillis = 1; 127 128 typedef WebSocketEventInterface::ChannelState ChannelState; 129 const ChannelState CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE; 130 const ChannelState CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED; 131 132 // This typedef mainly exists to avoid having to repeat the "NOLINT" incantation 133 // all over the place. 134 typedef MockFunction<void(int)> Checkpoint; // NOLINT 135 136 // This mock is for testing expectations about how the EventInterface is used. 137 class MockWebSocketEventInterface : public WebSocketEventInterface { 138 public: 139 MOCK_METHOD2(OnAddChannelResponse, 140 ChannelState(bool, const std::string&)); // NOLINT 141 MOCK_METHOD3(OnDataFrame, 142 ChannelState(bool, 143 WebSocketMessageType, 144 const std::vector<char>&)); // NOLINT 145 MOCK_METHOD1(OnFlowControl, ChannelState(int64)); // NOLINT 146 MOCK_METHOD0(OnClosingHandshake, ChannelState(void)); // NOLINT 147 MOCK_METHOD2(OnDropChannel, 148 ChannelState(uint16, const std::string&)); // NOLINT 149 }; 150 151 // This fake EventInterface is for tests which need a WebSocketEventInterface 152 // implementation but are not verifying how it is used. 153 class FakeWebSocketEventInterface : public WebSocketEventInterface { 154 virtual ChannelState OnAddChannelResponse( 155 bool fail, 156 const std::string& selected_protocol) OVERRIDE { 157 return fail ? CHANNEL_DELETED : CHANNEL_ALIVE; 158 } 159 virtual ChannelState OnDataFrame(bool fin, 160 WebSocketMessageType type, 161 const std::vector<char>& data) OVERRIDE { 162 return CHANNEL_ALIVE; 163 } 164 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { 165 return CHANNEL_ALIVE; 166 } 167 virtual ChannelState OnClosingHandshake() OVERRIDE { return CHANNEL_ALIVE; } 168 virtual ChannelState OnDropChannel(uint16 code, 169 const std::string& reason) OVERRIDE { 170 return CHANNEL_DELETED; 171 } 172 }; 173 174 // This fake WebSocketStream is for tests that require a WebSocketStream but are 175 // not testing the way it is used. It has minimal functionality to return 176 // the |protocol| and |extensions| that it was constructed with. 177 class FakeWebSocketStream : public WebSocketStream { 178 public: 179 // Constructs with empty protocol and extensions. 180 FakeWebSocketStream() {} 181 182 // Constructs with specified protocol and extensions. 183 FakeWebSocketStream(const std::string& protocol, 184 const std::string& extensions) 185 : protocol_(protocol), extensions_(extensions) {} 186 187 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 188 const CompletionCallback& callback) OVERRIDE { 189 return ERR_IO_PENDING; 190 } 191 192 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 193 const CompletionCallback& callback) OVERRIDE { 194 return ERR_IO_PENDING; 195 } 196 197 virtual void Close() OVERRIDE {} 198 199 // Returns the string passed to the constructor. 200 virtual std::string GetSubProtocol() const OVERRIDE { return protocol_; } 201 202 // Returns the string passed to the constructor. 203 virtual std::string GetExtensions() const OVERRIDE { return extensions_; } 204 205 private: 206 // The string to return from GetSubProtocol(). 207 std::string protocol_; 208 209 // The string to return from GetExtensions(). 210 std::string extensions_; 211 }; 212 213 // To make the static initialisers easier to read, we use enums rather than 214 // bools. 215 enum IsFinal { 216 NOT_FINAL_FRAME, 217 FINAL_FRAME 218 }; 219 220 enum IsMasked { 221 NOT_MASKED, 222 MASKED 223 }; 224 225 // This is used to initialise a WebSocketFrame but is statically initialisable. 226 struct InitFrame { 227 IsFinal final; 228 // Reserved fields omitted for now. Add them if you need them. 229 WebSocketFrameHeader::OpCode opcode; 230 IsMasked masked; 231 232 // Will be used to create the IOBuffer member. Can be NULL for NULL data. Is a 233 // nul-terminated string for ease-of-use. |header.payload_length| is 234 // initialised from |strlen(data)|. This means it is not 8-bit clean, but this 235 // is not an issue for test data. 236 const char* const data; 237 }; 238 239 // For GoogleMock 240 std::ostream& operator<<(std::ostream& os, const InitFrame& frame) { 241 os << "{" << (frame.final == FINAL_FRAME ? "FINAL_FRAME" : "NOT_FINAL_FRAME") 242 << ", " << frame.opcode << ", " 243 << (frame.masked == MASKED ? "MASKED" : "NOT_MASKED") << ", "; 244 if (frame.data) { 245 return os << "\"" << frame.data << "\"}"; 246 } 247 return os << "NULL}"; 248 } 249 250 template <size_t N> 251 std::ostream& operator<<(std::ostream& os, const InitFrame (&frames)[N]) { 252 os << "{"; 253 bool first = true; 254 for (size_t i = 0; i < N; ++i) { 255 if (!first) { 256 os << ",\n"; 257 } else { 258 first = false; 259 } 260 os << frames[i]; 261 } 262 return os << "}"; 263 } 264 265 // Convert a const array of InitFrame structs to the format used at 266 // runtime. Templated on the size of the array to save typing. 267 template <size_t N> 268 ScopedVector<WebSocketFrame> CreateFrameVector( 269 const InitFrame (&source_frames)[N]) { 270 ScopedVector<WebSocketFrame> result_frames; 271 result_frames.reserve(N); 272 for (size_t i = 0; i < N; ++i) { 273 const InitFrame& source_frame = source_frames[i]; 274 scoped_ptr<WebSocketFrame> result_frame( 275 new WebSocketFrame(source_frame.opcode)); 276 size_t frame_length = source_frame.data ? strlen(source_frame.data) : 0; 277 WebSocketFrameHeader& result_header = result_frame->header; 278 result_header.final = (source_frame.final == FINAL_FRAME); 279 result_header.masked = (source_frame.masked == MASKED); 280 result_header.payload_length = frame_length; 281 if (source_frame.data) { 282 result_frame->data = new IOBuffer(frame_length); 283 memcpy(result_frame->data->data(), source_frame.data, frame_length); 284 } 285 result_frames.push_back(result_frame.release()); 286 } 287 return result_frames.Pass(); 288 } 289 290 // A GoogleMock action which can be used to respond to call to ReadFrames with 291 // some frames. Use like ReadFrames(_, _).WillOnce(ReturnFrames(&frames)); 292 // |frames| is an array of InitFrame. |frames| needs to be passed by pointer 293 // because otherwise it will be treated as a pointer and the array size 294 // information will be lost. 295 ACTION_P(ReturnFrames, source_frames) { 296 *arg0 = CreateFrameVector(*source_frames); 297 return OK; 298 } 299 300 // The implementation of a GoogleMock matcher which can be used to compare a 301 // ScopedVector<WebSocketFrame>* against an expectation defined as an array of 302 // InitFrame objects. Although it is possible to compose built-in GoogleMock 303 // matchers to check the contents of a WebSocketFrame, the results are so 304 // unreadable that it is better to use this matcher. 305 template <size_t N> 306 class EqualsFramesMatcher 307 : public ::testing::MatcherInterface<ScopedVector<WebSocketFrame>*> { 308 public: 309 EqualsFramesMatcher(const InitFrame (*expect_frames)[N]) 310 : expect_frames_(expect_frames) {} 311 312 virtual bool MatchAndExplain(ScopedVector<WebSocketFrame>* actual_frames, 313 ::testing::MatchResultListener* listener) const { 314 if (actual_frames->size() != N) { 315 *listener << "the vector size is " << actual_frames->size(); 316 return false; 317 } 318 for (size_t i = 0; i < N; ++i) { 319 const WebSocketFrame& actual_frame = *(*actual_frames)[i]; 320 const InitFrame& expected_frame = (*expect_frames_)[i]; 321 if (actual_frame.header.final != (expected_frame.final == FINAL_FRAME)) { 322 *listener << "the frame is marked as " 323 << (actual_frame.header.final ? "" : "not ") << "final"; 324 return false; 325 } 326 if (actual_frame.header.opcode != expected_frame.opcode) { 327 *listener << "the opcode is " << actual_frame.header.opcode; 328 return false; 329 } 330 if (actual_frame.header.masked != (expected_frame.masked == MASKED)) { 331 *listener << "the frame is " 332 << (actual_frame.header.masked ? "masked" : "not masked"); 333 return false; 334 } 335 const size_t expected_length = 336 expected_frame.data ? strlen(expected_frame.data) : 0; 337 if (actual_frame.header.payload_length != expected_length) { 338 *listener << "the payload length is " 339 << actual_frame.header.payload_length; 340 return false; 341 } 342 if (expected_length != 0 && 343 memcmp(actual_frame.data->data(), 344 expected_frame.data, 345 actual_frame.header.payload_length) != 0) { 346 *listener << "the data content differs"; 347 return false; 348 } 349 } 350 return true; 351 } 352 353 virtual void DescribeTo(std::ostream* os) const { 354 *os << "matches " << *expect_frames_; 355 } 356 357 virtual void DescribeNegationTo(std::ostream* os) const { 358 *os << "does not match " << *expect_frames_; 359 } 360 361 private: 362 const InitFrame (*expect_frames_)[N]; 363 }; 364 365 // The definition of EqualsFrames GoogleMock matcher. Unlike the ReturnFrames 366 // action, this can take the array by reference. 367 template <size_t N> 368 ::testing::Matcher<ScopedVector<WebSocketFrame>*> EqualsFrames( 369 const InitFrame (&frames)[N]) { 370 return ::testing::MakeMatcher(new EqualsFramesMatcher<N>(&frames)); 371 } 372 373 // TestClosure works like TestCompletionCallback, but doesn't take an argument. 374 class TestClosure { 375 public: 376 base::Closure closure() { return base::Bind(callback_.callback(), OK); } 377 378 void WaitForResult() { callback_.WaitForResult(); } 379 380 private: 381 // Delegate to TestCompletionCallback for the implementation. 382 TestCompletionCallback callback_; 383 }; 384 385 // A GoogleMock action to run a Closure. 386 ACTION_P(InvokeClosure, closure) { closure.Run(); } 387 388 // A GoogleMock action to run a Closure and return CHANNEL_DELETED. 389 ACTION_P(InvokeClosureReturnDeleted, closure) { 390 closure.Run(); 391 return WebSocketEventInterface::CHANNEL_DELETED; 392 } 393 394 // A FakeWebSocketStream whose ReadFrames() function returns data. 395 class ReadableFakeWebSocketStream : public FakeWebSocketStream { 396 public: 397 enum IsSync { 398 SYNC, 399 ASYNC 400 }; 401 402 // After constructing the object, call PrepareReadFrames() once for each 403 // time you wish it to return from the test. 404 ReadableFakeWebSocketStream() : index_(0), read_frames_pending_(false) {} 405 406 // Check that all the prepared responses have been consumed. 407 virtual ~ReadableFakeWebSocketStream() { 408 CHECK(index_ >= responses_.size()); 409 CHECK(!read_frames_pending_); 410 } 411 412 // Prepares a fake response. Fake responses will be returned from ReadFrames() 413 // in the same order they were prepared with PrepareReadFrames() and 414 // PrepareReadFramesError(). If |async| is ASYNC, then ReadFrames() will 415 // return ERR_IO_PENDING and the callback will be scheduled to run on the 416 // message loop. This requires the test case to run the message loop. If 417 // |async| is SYNC, the response will be returned synchronously. |error| is 418 // returned directly from ReadFrames() in the synchronous case, or passed to 419 // the callback in the asynchronous case. |frames| will be converted to a 420 // ScopedVector<WebSocketFrame> and copied to the pointer that was passed to 421 // ReadFrames(). 422 template <size_t N> 423 void PrepareReadFrames(IsSync async, 424 int error, 425 const InitFrame (&frames)[N]) { 426 responses_.push_back(new Response(async, error, CreateFrameVector(frames))); 427 } 428 429 // An alternate version of PrepareReadFrames for when we need to construct 430 // the frames manually. 431 void PrepareRawReadFrames(IsSync async, 432 int error, 433 ScopedVector<WebSocketFrame> frames) { 434 responses_.push_back(new Response(async, error, frames.Pass())); 435 } 436 437 // Prepares a fake error response (ie. there is no data). 438 void PrepareReadFramesError(IsSync async, int error) { 439 responses_.push_back( 440 new Response(async, error, ScopedVector<WebSocketFrame>())); 441 } 442 443 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 444 const CompletionCallback& callback) OVERRIDE { 445 CHECK(!read_frames_pending_); 446 if (index_ >= responses_.size()) 447 return ERR_IO_PENDING; 448 if (responses_[index_]->async == ASYNC) { 449 read_frames_pending_ = true; 450 base::MessageLoop::current()->PostTask( 451 FROM_HERE, 452 base::Bind(&ReadableFakeWebSocketStream::DoCallback, 453 base::Unretained(this), 454 frames, 455 callback)); 456 return ERR_IO_PENDING; 457 } else { 458 frames->swap(responses_[index_]->frames); 459 return responses_[index_++]->error; 460 } 461 } 462 463 private: 464 void DoCallback(ScopedVector<WebSocketFrame>* frames, 465 const CompletionCallback& callback) { 466 read_frames_pending_ = false; 467 frames->swap(responses_[index_]->frames); 468 callback.Run(responses_[index_++]->error); 469 return; 470 } 471 472 struct Response { 473 Response(IsSync async, int error, ScopedVector<WebSocketFrame> frames) 474 : async(async), error(error), frames(frames.Pass()) {} 475 476 IsSync async; 477 int error; 478 ScopedVector<WebSocketFrame> frames; 479 480 private: 481 // Bad things will happen if we attempt to copy or assign |frames|. 482 DISALLOW_COPY_AND_ASSIGN(Response); 483 }; 484 ScopedVector<Response> responses_; 485 486 // The index into the responses_ array of the next response to be returned. 487 size_t index_; 488 489 // True when an async response from ReadFrames() is pending. This only applies 490 // to "real" async responses. Once all the prepared responses have been 491 // returned, ReadFrames() returns ERR_IO_PENDING but read_frames_pending_ is 492 // not set to true. 493 bool read_frames_pending_; 494 }; 495 496 // A FakeWebSocketStream where writes always complete successfully and 497 // synchronously. 498 class WriteableFakeWebSocketStream : public FakeWebSocketStream { 499 public: 500 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 501 const CompletionCallback& callback) OVERRIDE { 502 return OK; 503 } 504 }; 505 506 // A FakeWebSocketStream where writes always fail. 507 class UnWriteableFakeWebSocketStream : public FakeWebSocketStream { 508 public: 509 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 510 const CompletionCallback& callback) OVERRIDE { 511 return ERR_CONNECTION_RESET; 512 } 513 }; 514 515 // A FakeWebSocketStream which echoes any frames written back. Clears the 516 // "masked" header bit, but makes no other checks for validity. Tests using this 517 // must run the MessageLoop to receive the callback(s). If a message with opcode 518 // Close is echoed, then an ERR_CONNECTION_CLOSED is returned in the next 519 // callback. The test must do something to cause WriteFrames() to be called, 520 // otherwise the ReadFrames() callback will never be called. 521 class EchoeyFakeWebSocketStream : public FakeWebSocketStream { 522 public: 523 EchoeyFakeWebSocketStream() : read_frames_(NULL), done_(false) {} 524 525 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 526 const CompletionCallback& callback) OVERRIDE { 527 // Users of WebSocketStream will not expect the ReadFrames() callback to be 528 // called from within WriteFrames(), so post it to the message loop instead. 529 stored_frames_.insert(stored_frames_.end(), frames->begin(), frames->end()); 530 frames->weak_clear(); 531 PostCallback(); 532 return OK; 533 } 534 535 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 536 const CompletionCallback& callback) OVERRIDE { 537 read_callback_ = callback; 538 read_frames_ = frames; 539 if (done_) 540 PostCallback(); 541 return ERR_IO_PENDING; 542 } 543 544 private: 545 void PostCallback() { 546 base::MessageLoop::current()->PostTask( 547 FROM_HERE, 548 base::Bind(&EchoeyFakeWebSocketStream::DoCallback, 549 base::Unretained(this))); 550 } 551 552 void DoCallback() { 553 if (done_) { 554 read_callback_.Run(ERR_CONNECTION_CLOSED); 555 } else if (!stored_frames_.empty()) { 556 done_ = MoveFrames(read_frames_); 557 read_frames_ = NULL; 558 read_callback_.Run(OK); 559 } 560 } 561 562 // Copy the frames stored in stored_frames_ to |out|, while clearing the 563 // "masked" header bit. Returns true if a Close Frame was seen, false 564 // otherwise. 565 bool MoveFrames(ScopedVector<WebSocketFrame>* out) { 566 bool seen_close = false; 567 *out = stored_frames_.Pass(); 568 for (ScopedVector<WebSocketFrame>::iterator it = out->begin(); 569 it != out->end(); 570 ++it) { 571 WebSocketFrameHeader& header = (*it)->header; 572 header.masked = false; 573 if (header.opcode == WebSocketFrameHeader::kOpCodeClose) 574 seen_close = true; 575 } 576 return seen_close; 577 } 578 579 ScopedVector<WebSocketFrame> stored_frames_; 580 CompletionCallback read_callback_; 581 // Owned by the caller of ReadFrames(). 582 ScopedVector<WebSocketFrame>* read_frames_; 583 // True if we should close the connection. 584 bool done_; 585 }; 586 587 // A FakeWebSocketStream where writes trigger a connection reset. 588 // This differs from UnWriteableFakeWebSocketStream in that it is asynchronous 589 // and triggers ReadFrames to return a reset as well. Tests using this need to 590 // run the message loop. There are two tricky parts here: 591 // 1. Calling the write callback may call Close(), after which the read callback 592 // should not be called. 593 // 2. Calling either callback may delete the stream altogether. 594 class ResetOnWriteFakeWebSocketStream : public FakeWebSocketStream { 595 public: 596 ResetOnWriteFakeWebSocketStream() : closed_(false), weak_ptr_factory_(this) {} 597 598 virtual int WriteFrames(ScopedVector<WebSocketFrame>* frames, 599 const CompletionCallback& callback) OVERRIDE { 600 base::MessageLoop::current()->PostTask( 601 FROM_HERE, 602 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, 603 weak_ptr_factory_.GetWeakPtr(), 604 callback, 605 ERR_CONNECTION_RESET)); 606 base::MessageLoop::current()->PostTask( 607 FROM_HERE, 608 base::Bind(&ResetOnWriteFakeWebSocketStream::CallCallbackUnlessClosed, 609 weak_ptr_factory_.GetWeakPtr(), 610 read_callback_, 611 ERR_CONNECTION_RESET)); 612 return ERR_IO_PENDING; 613 } 614 615 virtual int ReadFrames(ScopedVector<WebSocketFrame>* frames, 616 const CompletionCallback& callback) OVERRIDE { 617 read_callback_ = callback; 618 return ERR_IO_PENDING; 619 } 620 621 virtual void Close() OVERRIDE { closed_ = true; } 622 623 private: 624 void CallCallbackUnlessClosed(const CompletionCallback& callback, int value) { 625 if (!closed_) 626 callback.Run(value); 627 } 628 629 CompletionCallback read_callback_; 630 bool closed_; 631 // An IO error can result in the socket being deleted, so we use weak pointers 632 // to ensure correct behaviour in that case. 633 base::WeakPtrFactory<ResetOnWriteFakeWebSocketStream> weak_ptr_factory_; 634 }; 635 636 // This mock is for verifying that WebSocket protocol semantics are obeyed (to 637 // the extent that they are implemented in WebSocketCommon). 638 class MockWebSocketStream : public WebSocketStream { 639 public: 640 MOCK_METHOD2(ReadFrames, 641 int(ScopedVector<WebSocketFrame>* frames, 642 const CompletionCallback& callback)); 643 MOCK_METHOD2(WriteFrames, 644 int(ScopedVector<WebSocketFrame>* frames, 645 const CompletionCallback& callback)); 646 MOCK_METHOD0(Close, void()); 647 MOCK_CONST_METHOD0(GetSubProtocol, std::string()); 648 MOCK_CONST_METHOD0(GetExtensions, std::string()); 649 MOCK_METHOD0(AsWebSocketStream, WebSocketStream*()); 650 }; 651 652 struct ArgumentCopyingWebSocketStreamCreator { 653 scoped_ptr<WebSocketStreamRequest> Create( 654 const GURL& socket_url, 655 const std::vector<std::string>& requested_subprotocols, 656 const GURL& origin, 657 URLRequestContext* url_request_context, 658 const BoundNetLog& net_log, 659 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate) { 660 this->socket_url = socket_url; 661 this->requested_subprotocols = requested_subprotocols; 662 this->origin = origin; 663 this->url_request_context = url_request_context; 664 this->net_log = net_log; 665 this->connect_delegate = connect_delegate.Pass(); 666 return make_scoped_ptr(new WebSocketStreamRequest); 667 } 668 669 GURL socket_url; 670 GURL origin; 671 std::vector<std::string> requested_subprotocols; 672 URLRequestContext* url_request_context; 673 BoundNetLog net_log; 674 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate; 675 }; 676 677 // Converts a std::string to a std::vector<char>. For test purposes, it is 678 // convenient to be able to specify data as a string, but the 679 // WebSocketEventInterface requires the vector<char> type. 680 std::vector<char> AsVector(const std::string& s) { 681 return std::vector<char>(s.begin(), s.end()); 682 } 683 684 // Base class for all test fixtures. 685 class WebSocketChannelTest : public ::testing::Test { 686 protected: 687 WebSocketChannelTest() : stream_(new FakeWebSocketStream) {} 688 689 // Creates a new WebSocketChannel and connects it, using the settings stored 690 // in |connect_data_|. 691 void CreateChannelAndConnect() { 692 channel_.reset(new WebSocketChannel(CreateEventInterface(), 693 &connect_data_.url_request_context)); 694 channel_->SendAddChannelRequestForTesting( 695 connect_data_.socket_url, 696 connect_data_.requested_subprotocols, 697 connect_data_.origin, 698 base::Bind(&ArgumentCopyingWebSocketStreamCreator::Create, 699 base::Unretained(&connect_data_.creator))); 700 } 701 702 // Same as CreateChannelAndConnect(), but calls the on_success callback as 703 // well. This method is virtual so that subclasses can also set the stream. 704 virtual void CreateChannelAndConnectSuccessfully() { 705 CreateChannelAndConnect(); 706 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 707 } 708 709 // Returns a WebSocketEventInterface to be passed to the WebSocketChannel. 710 // This implementation returns a newly-created fake. Subclasses may return a 711 // mock instead. 712 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() { 713 return scoped_ptr<WebSocketEventInterface>(new FakeWebSocketEventInterface); 714 } 715 716 // This method serves no other purpose than to provide a nice syntax for 717 // assigning to stream_. class T must be a subclass of WebSocketStream or you 718 // will have unpleasant compile errors. 719 template <class T> 720 void set_stream(scoped_ptr<T> stream) { 721 // Since the definition of "PassAs" depends on the type T, the C++ standard 722 // requires the "template" keyword to indicate that "PassAs" should be 723 // parsed as a template method. 724 stream_ = stream.template PassAs<WebSocketStream>(); 725 } 726 727 // A struct containing the data that will be used to connect the channel. 728 // Grouped for readability. 729 struct ConnectData { 730 ConnectData() : 731 socket_url("ws://ws/"), 732 origin("http://ws/") 733 {} 734 735 // URLRequestContext object. 736 URLRequestContext url_request_context; 737 738 // URL to (pretend to) connect to. 739 GURL socket_url; 740 // Requested protocols for the request. 741 std::vector<std::string> requested_subprotocols; 742 // Origin of the request 743 GURL origin; 744 745 // A fake WebSocketStreamCreator that just records its arguments. 746 ArgumentCopyingWebSocketStreamCreator creator; 747 }; 748 ConnectData connect_data_; 749 750 // The channel we are testing. Not initialised until SetChannel() is called. 751 scoped_ptr<WebSocketChannel> channel_; 752 753 // A mock or fake stream for tests that need one. 754 scoped_ptr<WebSocketStream> stream_; 755 }; 756 757 // enum of WebSocketEventInterface calls. These are intended to be or'd together 758 // in order to instruct WebSocketChannelDeletingTest when it should fail. 759 enum EventInterfaceCall { 760 EVENT_ON_ADD_CHANNEL_RESPONSE = 0x1, 761 EVENT_ON_DATA_FRAME = 0x2, 762 EVENT_ON_FLOW_CONTROL = 0x4, 763 EVENT_ON_CLOSING_HANDSHAKE = 0x8, 764 EVENT_ON_DROP_CHANNEL = 0x10, 765 }; 766 767 class WebSocketChannelDeletingTest : public WebSocketChannelTest { 768 public: 769 ChannelState DeleteIfDeleting(EventInterfaceCall call) { 770 if (deleting_ & call) { 771 channel_.reset(); 772 return CHANNEL_DELETED; 773 } else { 774 return CHANNEL_ALIVE; 775 } 776 } 777 778 protected: 779 WebSocketChannelDeletingTest() 780 : deleting_(EVENT_ON_ADD_CHANNEL_RESPONSE | EVENT_ON_DATA_FRAME | 781 EVENT_ON_FLOW_CONTROL | 782 EVENT_ON_CLOSING_HANDSHAKE | 783 EVENT_ON_DROP_CHANNEL) {} 784 // Create a ChannelDeletingFakeWebSocketEventInterface. Defined out-of-line to 785 // avoid circular dependency. 786 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE; 787 788 // Tests can set deleting_ to a bitmap of EventInterfaceCall members that they 789 // want to cause Channel deletion. The default is for all calls to cause 790 // deletion. 791 int deleting_; 792 }; 793 794 // A FakeWebSocketEventInterface that deletes the WebSocketChannel on failure to 795 // connect. 796 class ChannelDeletingFakeWebSocketEventInterface 797 : public FakeWebSocketEventInterface { 798 public: 799 ChannelDeletingFakeWebSocketEventInterface( 800 WebSocketChannelDeletingTest* fixture) 801 : fixture_(fixture) {} 802 803 virtual ChannelState OnAddChannelResponse( 804 bool fail, 805 const std::string& selected_protocol) OVERRIDE { 806 return fixture_->DeleteIfDeleting(EVENT_ON_ADD_CHANNEL_RESPONSE); 807 } 808 809 virtual ChannelState OnDataFrame(bool fin, 810 WebSocketMessageType type, 811 const std::vector<char>& data) OVERRIDE { 812 return fixture_->DeleteIfDeleting(EVENT_ON_DATA_FRAME); 813 } 814 815 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE { 816 return fixture_->DeleteIfDeleting(EVENT_ON_FLOW_CONTROL); 817 } 818 819 virtual ChannelState OnClosingHandshake() OVERRIDE { 820 return fixture_->DeleteIfDeleting(EVENT_ON_CLOSING_HANDSHAKE); 821 } 822 823 virtual ChannelState OnDropChannel(uint16 code, 824 const std::string& reason) OVERRIDE { 825 return fixture_->DeleteIfDeleting(EVENT_ON_DROP_CHANNEL); 826 } 827 828 private: 829 // A pointer to the test fixture. Owned by the test harness; this object will 830 // be deleted before it is. 831 WebSocketChannelDeletingTest* fixture_; 832 }; 833 834 scoped_ptr<WebSocketEventInterface> 835 WebSocketChannelDeletingTest::CreateEventInterface() { 836 return scoped_ptr<WebSocketEventInterface>( 837 new ChannelDeletingFakeWebSocketEventInterface(this)); 838 } 839 840 // Base class for tests which verify that EventInterface methods are called 841 // appropriately. 842 class WebSocketChannelEventInterfaceTest : public WebSocketChannelTest { 843 protected: 844 WebSocketChannelEventInterfaceTest() 845 : event_interface_(new StrictMock<MockWebSocketEventInterface>) { 846 DefaultValue<ChannelState>::Set(CHANNEL_ALIVE); 847 ON_CALL(*event_interface_, OnAddChannelResponse(true, _)) 848 .WillByDefault(Return(CHANNEL_DELETED)); 849 ON_CALL(*event_interface_, OnDropChannel(_, _)) 850 .WillByDefault(Return(CHANNEL_DELETED)); 851 } 852 853 virtual ~WebSocketChannelEventInterfaceTest() { 854 DefaultValue<ChannelState>::Clear(); 855 } 856 857 // Tests using this fixture must set expectations on the event_interface_ mock 858 // object before calling CreateChannelAndConnect() or 859 // CreateChannelAndConnectSuccessfully(). This will only work once per test 860 // case, but once should be enough. 861 virtual scoped_ptr<WebSocketEventInterface> CreateEventInterface() OVERRIDE { 862 return scoped_ptr<WebSocketEventInterface>(event_interface_.release()); 863 } 864 865 scoped_ptr<MockWebSocketEventInterface> event_interface_; 866 }; 867 868 // Base class for tests which verify that WebSocketStream methods are called 869 // appropriately by using a MockWebSocketStream. 870 class WebSocketChannelStreamTest : public WebSocketChannelTest { 871 protected: 872 WebSocketChannelStreamTest() 873 : mock_stream_(new StrictMock<MockWebSocketStream>) {} 874 875 virtual void CreateChannelAndConnectSuccessfully() OVERRIDE { 876 set_stream(mock_stream_.Pass()); 877 WebSocketChannelTest::CreateChannelAndConnectSuccessfully(); 878 } 879 880 scoped_ptr<MockWebSocketStream> mock_stream_; 881 }; 882 883 // Simple test that everything that should be passed to the creator function is 884 // passed to the creator function. 885 TEST_F(WebSocketChannelTest, EverythingIsPassedToTheCreatorFunction) { 886 connect_data_.socket_url = GURL("ws://example.com/test"); 887 connect_data_.origin = GURL("http://example.com/test"); 888 connect_data_.requested_subprotocols.push_back("Sinbad"); 889 890 CreateChannelAndConnect(); 891 892 const ArgumentCopyingWebSocketStreamCreator& actual = connect_data_.creator; 893 894 EXPECT_EQ(&connect_data_.url_request_context, actual.url_request_context); 895 896 EXPECT_EQ(connect_data_.socket_url, actual.socket_url); 897 EXPECT_EQ(connect_data_.requested_subprotocols, 898 actual.requested_subprotocols); 899 EXPECT_EQ(connect_data_.origin, actual.origin); 900 } 901 902 // Verify that calling SendFlowControl before the connection is established does 903 // not cause a crash. 904 TEST_F(WebSocketChannelTest, SendFlowControlDuringHandshakeOkay) { 905 CreateChannelAndConnect(); 906 ASSERT_TRUE(channel_); 907 channel_->SendFlowControl(65536); 908 } 909 910 // Any WebSocketEventInterface methods can delete the WebSocketChannel and 911 // return CHANNEL_DELETED. The WebSocketChannelDeletingTests are intended to 912 // verify that there are no use-after-free bugs when this happens. Problems will 913 // probably only be found when running under Address Sanitizer or a similar 914 // tool. 915 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseFail) { 916 CreateChannelAndConnect(); 917 EXPECT_TRUE(channel_); 918 connect_data_.creator.connect_delegate->OnFailure( 919 kWebSocketErrorNoStatusReceived); 920 EXPECT_EQ(NULL, channel_.get()); 921 } 922 923 // Deletion is possible (due to IPC failure) even if the connect succeeds. 924 TEST_F(WebSocketChannelDeletingTest, OnAddChannelResponseSuccess) { 925 CreateChannelAndConnectSuccessfully(); 926 EXPECT_EQ(NULL, channel_.get()); 927 } 928 929 TEST_F(WebSocketChannelDeletingTest, OnDataFrameSync) { 930 scoped_ptr<ReadableFakeWebSocketStream> stream( 931 new ReadableFakeWebSocketStream); 932 static const InitFrame frames[] = { 933 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 934 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 935 set_stream(stream.Pass()); 936 deleting_ = EVENT_ON_DATA_FRAME; 937 938 CreateChannelAndConnectSuccessfully(); 939 EXPECT_EQ(NULL, channel_.get()); 940 } 941 942 TEST_F(WebSocketChannelDeletingTest, OnDataFrameAsync) { 943 scoped_ptr<ReadableFakeWebSocketStream> stream( 944 new ReadableFakeWebSocketStream); 945 static const InitFrame frames[] = { 946 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 947 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 948 set_stream(stream.Pass()); 949 deleting_ = EVENT_ON_DATA_FRAME; 950 951 CreateChannelAndConnectSuccessfully(); 952 EXPECT_TRUE(channel_); 953 base::MessageLoop::current()->RunUntilIdle(); 954 EXPECT_EQ(NULL, channel_.get()); 955 } 956 957 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterConnect) { 958 deleting_ = EVENT_ON_FLOW_CONTROL; 959 960 CreateChannelAndConnectSuccessfully(); 961 EXPECT_EQ(NULL, channel_.get()); 962 } 963 964 TEST_F(WebSocketChannelDeletingTest, OnFlowControlAfterSend) { 965 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 966 // Avoid deleting the channel yet. 967 deleting_ = EVENT_ON_DROP_CHANNEL; 968 CreateChannelAndConnectSuccessfully(); 969 ASSERT_TRUE(channel_); 970 deleting_ = EVENT_ON_FLOW_CONTROL; 971 channel_->SendFrame(true, 972 WebSocketFrameHeader::kOpCodeText, 973 std::vector<char>(kDefaultInitialQuota, 'B')); 974 EXPECT_EQ(NULL, channel_.get()); 975 } 976 977 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeSync) { 978 scoped_ptr<ReadableFakeWebSocketStream> stream( 979 new ReadableFakeWebSocketStream); 980 static const InitFrame frames[] = { 981 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 982 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 983 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 984 set_stream(stream.Pass()); 985 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; 986 CreateChannelAndConnectSuccessfully(); 987 EXPECT_EQ(NULL, channel_.get()); 988 } 989 990 TEST_F(WebSocketChannelDeletingTest, OnClosingHandshakeAsync) { 991 scoped_ptr<ReadableFakeWebSocketStream> stream( 992 new ReadableFakeWebSocketStream); 993 static const InitFrame frames[] = { 994 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 995 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 996 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 997 set_stream(stream.Pass()); 998 deleting_ = EVENT_ON_CLOSING_HANDSHAKE; 999 CreateChannelAndConnectSuccessfully(); 1000 ASSERT_TRUE(channel_); 1001 base::MessageLoop::current()->RunUntilIdle(); 1002 EXPECT_EQ(NULL, channel_.get()); 1003 } 1004 1005 TEST_F(WebSocketChannelDeletingTest, OnDropChannelWriteError) { 1006 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); 1007 deleting_ = EVENT_ON_DROP_CHANNEL; 1008 CreateChannelAndConnectSuccessfully(); 1009 ASSERT_TRUE(channel_); 1010 channel_->SendFrame( 1011 true, WebSocketFrameHeader::kOpCodeText, AsVector("this will fail")); 1012 EXPECT_EQ(NULL, channel_.get()); 1013 } 1014 1015 TEST_F(WebSocketChannelDeletingTest, OnDropChannelReadError) { 1016 scoped_ptr<ReadableFakeWebSocketStream> stream( 1017 new ReadableFakeWebSocketStream); 1018 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1019 ERR_FAILED); 1020 set_stream(stream.Pass()); 1021 deleting_ = EVENT_ON_DROP_CHANNEL; 1022 CreateChannelAndConnectSuccessfully(); 1023 ASSERT_TRUE(channel_); 1024 base::MessageLoop::current()->RunUntilIdle(); 1025 EXPECT_EQ(NULL, channel_.get()); 1026 } 1027 1028 TEST_F(WebSocketChannelDeletingTest, FailChannelInSendFrame) { 1029 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1030 deleting_ = EVENT_ON_DROP_CHANNEL; 1031 CreateChannelAndConnectSuccessfully(); 1032 ASSERT_TRUE(channel_); 1033 channel_->SendFrame(true, 1034 WebSocketFrameHeader::kOpCodeText, 1035 std::vector<char>(kDefaultInitialQuota * 2, 'T')); 1036 EXPECT_EQ(NULL, channel_.get()); 1037 } 1038 1039 TEST_F(WebSocketChannelDeletingTest, FailChannelInOnReadDone) { 1040 scoped_ptr<ReadableFakeWebSocketStream> stream( 1041 new ReadableFakeWebSocketStream); 1042 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1043 ERR_WS_PROTOCOL_ERROR); 1044 set_stream(stream.Pass()); 1045 deleting_ = EVENT_ON_DROP_CHANNEL; 1046 CreateChannelAndConnectSuccessfully(); 1047 ASSERT_TRUE(channel_); 1048 base::MessageLoop::current()->RunUntilIdle(); 1049 EXPECT_EQ(NULL, channel_.get()); 1050 } 1051 1052 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToMaskedFrame) { 1053 scoped_ptr<ReadableFakeWebSocketStream> stream( 1054 new ReadableFakeWebSocketStream); 1055 static const InitFrame frames[] = { 1056 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; 1057 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1058 set_stream(stream.Pass()); 1059 deleting_ = EVENT_ON_DROP_CHANNEL; 1060 1061 CreateChannelAndConnectSuccessfully(); 1062 EXPECT_EQ(NULL, channel_.get()); 1063 } 1064 1065 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrame) { 1066 scoped_ptr<ReadableFakeWebSocketStream> stream( 1067 new ReadableFakeWebSocketStream); 1068 static const InitFrame frames[] = { 1069 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; 1070 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1071 set_stream(stream.Pass()); 1072 deleting_ = EVENT_ON_DROP_CHANNEL; 1073 1074 CreateChannelAndConnectSuccessfully(); 1075 EXPECT_EQ(NULL, channel_.get()); 1076 } 1077 1078 // Version of above test with NULL data. 1079 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToBadControlFrameNull) { 1080 scoped_ptr<ReadableFakeWebSocketStream> stream( 1081 new ReadableFakeWebSocketStream); 1082 static const InitFrame frames[] = { 1083 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}}; 1084 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1085 set_stream(stream.Pass()); 1086 deleting_ = EVENT_ON_DROP_CHANNEL; 1087 1088 CreateChannelAndConnectSuccessfully(); 1089 EXPECT_EQ(NULL, channel_.get()); 1090 } 1091 1092 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterClose) { 1093 scoped_ptr<ReadableFakeWebSocketStream> stream( 1094 new ReadableFakeWebSocketStream); 1095 static const InitFrame frames[] = { 1096 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 1097 CLOSE_DATA(NORMAL_CLOSURE, "Success")}, 1098 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; 1099 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1100 set_stream(stream.Pass()); 1101 deleting_ = EVENT_ON_DROP_CHANNEL; 1102 1103 CreateChannelAndConnectSuccessfully(); 1104 EXPECT_EQ(NULL, channel_.get()); 1105 } 1106 1107 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToPongAfterCloseNull) { 1108 scoped_ptr<ReadableFakeWebSocketStream> stream( 1109 new ReadableFakeWebSocketStream); 1110 static const InitFrame frames[] = { 1111 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, 1112 CLOSE_DATA(NORMAL_CLOSURE, "Success")}, 1113 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}}; 1114 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1115 set_stream(stream.Pass()); 1116 deleting_ = EVENT_ON_DROP_CHANNEL; 1117 1118 CreateChannelAndConnectSuccessfully(); 1119 EXPECT_EQ(NULL, channel_.get()); 1120 } 1121 1122 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCode) { 1123 scoped_ptr<ReadableFakeWebSocketStream> stream( 1124 new ReadableFakeWebSocketStream); 1125 static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, ""}}; 1126 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1127 set_stream(stream.Pass()); 1128 deleting_ = EVENT_ON_DROP_CHANNEL; 1129 1130 CreateChannelAndConnectSuccessfully(); 1131 EXPECT_EQ(NULL, channel_.get()); 1132 } 1133 1134 TEST_F(WebSocketChannelDeletingTest, FailChannelDueToUnknownOpCodeNull) { 1135 scoped_ptr<ReadableFakeWebSocketStream> stream( 1136 new ReadableFakeWebSocketStream); 1137 static const InitFrame frames[] = {{FINAL_FRAME, 0x7, NOT_MASKED, NULL}}; 1138 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1139 set_stream(stream.Pass()); 1140 deleting_ = EVENT_ON_DROP_CHANNEL; 1141 1142 CreateChannelAndConnectSuccessfully(); 1143 EXPECT_EQ(NULL, channel_.get()); 1144 } 1145 1146 TEST_F(WebSocketChannelEventInterfaceTest, ConnectSuccessReported) { 1147 // false means success. 1148 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "")); 1149 // OnFlowControl is always called immediately after connect to provide initial 1150 // quota to the renderer. 1151 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1152 1153 CreateChannelAndConnect(); 1154 1155 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 1156 } 1157 1158 TEST_F(WebSocketChannelEventInterfaceTest, ConnectFailureReported) { 1159 // true means failure. 1160 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "")); 1161 1162 CreateChannelAndConnect(); 1163 1164 connect_data_.creator.connect_delegate->OnFailure( 1165 kWebSocketErrorNoStatusReceived); 1166 } 1167 1168 TEST_F(WebSocketChannelEventInterfaceTest, NonWebSocketSchemeRejected) { 1169 EXPECT_CALL(*event_interface_, OnAddChannelResponse(true, "")); 1170 connect_data_.socket_url = GURL("http://www.google.com/"); 1171 CreateChannelAndConnect(); 1172 } 1173 1174 TEST_F(WebSocketChannelEventInterfaceTest, ProtocolPassed) { 1175 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, "Bob")); 1176 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1177 1178 CreateChannelAndConnect(); 1179 1180 connect_data_.creator.connect_delegate->OnSuccess( 1181 scoped_ptr<WebSocketStream>(new FakeWebSocketStream("Bob", ""))); 1182 } 1183 1184 // The first frames from the server can arrive together with the handshake, in 1185 // which case they will be available as soon as ReadFrames() is called the first 1186 // time. 1187 TEST_F(WebSocketChannelEventInterfaceTest, DataLeftFromHandshake) { 1188 scoped_ptr<ReadableFakeWebSocketStream> stream( 1189 new ReadableFakeWebSocketStream); 1190 static const InitFrame frames[] = { 1191 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1192 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1193 set_stream(stream.Pass()); 1194 { 1195 InSequence s; 1196 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1197 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1198 EXPECT_CALL( 1199 *event_interface_, 1200 OnDataFrame( 1201 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 1202 } 1203 1204 CreateChannelAndConnectSuccessfully(); 1205 } 1206 1207 // A remote server could accept the handshake, but then immediately send a 1208 // Close frame. 1209 TEST_F(WebSocketChannelEventInterfaceTest, CloseAfterHandshake) { 1210 scoped_ptr<ReadableFakeWebSocketStream> stream( 1211 new ReadableFakeWebSocketStream); 1212 static const InitFrame frames[] = { 1213 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1214 NOT_MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Server Error")}}; 1215 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1216 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1217 ERR_CONNECTION_CLOSED); 1218 set_stream(stream.Pass()); 1219 { 1220 InSequence s; 1221 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1222 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1223 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1224 EXPECT_CALL(*event_interface_, 1225 OnDropChannel(kWebSocketErrorInternalServerError, 1226 "Internal Server Error")); 1227 } 1228 1229 CreateChannelAndConnectSuccessfully(); 1230 } 1231 1232 // A remote server could close the connection immediately after sending the 1233 // handshake response (most likely a bug in the server). 1234 TEST_F(WebSocketChannelEventInterfaceTest, ConnectionCloseAfterHandshake) { 1235 scoped_ptr<ReadableFakeWebSocketStream> stream( 1236 new ReadableFakeWebSocketStream); 1237 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1238 ERR_CONNECTION_CLOSED); 1239 set_stream(stream.Pass()); 1240 { 1241 InSequence s; 1242 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1243 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1244 EXPECT_CALL(*event_interface_, 1245 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); 1246 } 1247 1248 CreateChannelAndConnectSuccessfully(); 1249 } 1250 1251 TEST_F(WebSocketChannelEventInterfaceTest, NormalAsyncRead) { 1252 scoped_ptr<ReadableFakeWebSocketStream> stream( 1253 new ReadableFakeWebSocketStream); 1254 static const InitFrame frames[] = { 1255 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1256 // We use this checkpoint object to verify that the callback isn't called 1257 // until we expect it to be. 1258 Checkpoint checkpoint; 1259 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1260 set_stream(stream.Pass()); 1261 { 1262 InSequence s; 1263 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1264 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1265 EXPECT_CALL(checkpoint, Call(1)); 1266 EXPECT_CALL( 1267 *event_interface_, 1268 OnDataFrame( 1269 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 1270 EXPECT_CALL(checkpoint, Call(2)); 1271 } 1272 1273 CreateChannelAndConnectSuccessfully(); 1274 checkpoint.Call(1); 1275 base::MessageLoop::current()->RunUntilIdle(); 1276 checkpoint.Call(2); 1277 } 1278 1279 // Extra data can arrive while a read is being processed, resulting in the next 1280 // read completing synchronously. 1281 TEST_F(WebSocketChannelEventInterfaceTest, AsyncThenSyncRead) { 1282 scoped_ptr<ReadableFakeWebSocketStream> stream( 1283 new ReadableFakeWebSocketStream); 1284 static const InitFrame frames1[] = { 1285 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "HELLO"}}; 1286 static const InitFrame frames2[] = { 1287 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "WORLD"}}; 1288 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); 1289 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames2); 1290 set_stream(stream.Pass()); 1291 { 1292 InSequence s; 1293 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1294 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1295 EXPECT_CALL( 1296 *event_interface_, 1297 OnDataFrame( 1298 true, WebSocketFrameHeader::kOpCodeText, AsVector("HELLO"))); 1299 EXPECT_CALL( 1300 *event_interface_, 1301 OnDataFrame( 1302 true, WebSocketFrameHeader::kOpCodeText, AsVector("WORLD"))); 1303 } 1304 1305 CreateChannelAndConnectSuccessfully(); 1306 base::MessageLoop::current()->RunUntilIdle(); 1307 } 1308 1309 // Data frames are delivered the same regardless of how many reads they arrive 1310 // as. 1311 TEST_F(WebSocketChannelEventInterfaceTest, FragmentedMessage) { 1312 scoped_ptr<ReadableFakeWebSocketStream> stream( 1313 new ReadableFakeWebSocketStream); 1314 // Here we have one message which arrived in five frames split across three 1315 // reads. It may have been reframed on arrival, but this class doesn't care 1316 // about that. 1317 static const InitFrame frames1[] = { 1318 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, "THREE"}, 1319 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1320 NOT_MASKED, " "}}; 1321 static const InitFrame frames2[] = { 1322 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1323 NOT_MASKED, "SMALL"}}; 1324 static const InitFrame frames3[] = { 1325 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1326 NOT_MASKED, " "}, 1327 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1328 NOT_MASKED, "FRAMES"}}; 1329 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); 1330 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2); 1331 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3); 1332 set_stream(stream.Pass()); 1333 { 1334 InSequence s; 1335 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1336 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1337 EXPECT_CALL( 1338 *event_interface_, 1339 OnDataFrame( 1340 false, WebSocketFrameHeader::kOpCodeText, AsVector("THREE"))); 1341 EXPECT_CALL( 1342 *event_interface_, 1343 OnDataFrame( 1344 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector(" "))); 1345 EXPECT_CALL(*event_interface_, 1346 OnDataFrame(false, 1347 WebSocketFrameHeader::kOpCodeContinuation, 1348 AsVector("SMALL"))); 1349 EXPECT_CALL( 1350 *event_interface_, 1351 OnDataFrame( 1352 false, WebSocketFrameHeader::kOpCodeContinuation, AsVector(" "))); 1353 EXPECT_CALL(*event_interface_, 1354 OnDataFrame(true, 1355 WebSocketFrameHeader::kOpCodeContinuation, 1356 AsVector("FRAMES"))); 1357 } 1358 1359 CreateChannelAndConnectSuccessfully(); 1360 base::MessageLoop::current()->RunUntilIdle(); 1361 } 1362 1363 // A message can consist of one frame with NULL payload. 1364 TEST_F(WebSocketChannelEventInterfaceTest, NullMessage) { 1365 scoped_ptr<ReadableFakeWebSocketStream> stream( 1366 new ReadableFakeWebSocketStream); 1367 static const InitFrame frames[] = { 1368 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, NULL}}; 1369 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1370 set_stream(stream.Pass()); 1371 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1372 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1373 EXPECT_CALL( 1374 *event_interface_, 1375 OnDataFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector(""))); 1376 CreateChannelAndConnectSuccessfully(); 1377 } 1378 1379 // A control frame is not permitted to be split into multiple frames. RFC6455 1380 // 5.5 "All control frames ... MUST NOT be fragmented." 1381 TEST_F(WebSocketChannelEventInterfaceTest, MultiFrameControlMessageIsRejected) { 1382 scoped_ptr<ReadableFakeWebSocketStream> stream( 1383 new ReadableFakeWebSocketStream); 1384 static const InitFrame frames[] = { 1385 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, "Pi"}, 1386 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1387 NOT_MASKED, "ng"}}; 1388 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1389 set_stream(stream.Pass()); 1390 { 1391 InSequence s; 1392 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1393 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1394 EXPECT_CALL(*event_interface_, 1395 OnDropChannel(kWebSocketErrorProtocolError, _)); 1396 } 1397 1398 CreateChannelAndConnectSuccessfully(); 1399 base::MessageLoop::current()->RunUntilIdle(); 1400 } 1401 1402 // Connection closed by the remote host without a closing handshake. 1403 TEST_F(WebSocketChannelEventInterfaceTest, AsyncAbnormalClosure) { 1404 scoped_ptr<ReadableFakeWebSocketStream> stream( 1405 new ReadableFakeWebSocketStream); 1406 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1407 ERR_CONNECTION_CLOSED); 1408 set_stream(stream.Pass()); 1409 { 1410 InSequence s; 1411 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1412 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1413 EXPECT_CALL(*event_interface_, 1414 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); 1415 } 1416 1417 CreateChannelAndConnectSuccessfully(); 1418 base::MessageLoop::current()->RunUntilIdle(); 1419 } 1420 1421 // A connection reset should produce the same event as an unexpected closure. 1422 TEST_F(WebSocketChannelEventInterfaceTest, ConnectionReset) { 1423 scoped_ptr<ReadableFakeWebSocketStream> stream( 1424 new ReadableFakeWebSocketStream); 1425 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1426 ERR_CONNECTION_RESET); 1427 set_stream(stream.Pass()); 1428 { 1429 InSequence s; 1430 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1431 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1432 EXPECT_CALL(*event_interface_, 1433 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); 1434 } 1435 1436 CreateChannelAndConnectSuccessfully(); 1437 base::MessageLoop::current()->RunUntilIdle(); 1438 } 1439 1440 // RFC6455 5.1 "A client MUST close a connection if it detects a masked frame." 1441 TEST_F(WebSocketChannelEventInterfaceTest, MaskedFramesAreRejected) { 1442 scoped_ptr<ReadableFakeWebSocketStream> stream( 1443 new ReadableFakeWebSocketStream); 1444 static const InitFrame frames[] = { 1445 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}}; 1446 1447 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1448 set_stream(stream.Pass()); 1449 { 1450 InSequence s; 1451 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1452 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1453 EXPECT_CALL(*event_interface_, 1454 OnDropChannel(kWebSocketErrorProtocolError, _)); 1455 } 1456 1457 CreateChannelAndConnectSuccessfully(); 1458 base::MessageLoop::current()->RunUntilIdle(); 1459 } 1460 1461 // RFC6455 5.2 "If an unknown opcode is received, the receiving endpoint MUST 1462 // _Fail the WebSocket Connection_." 1463 TEST_F(WebSocketChannelEventInterfaceTest, UnknownOpCodeIsRejected) { 1464 scoped_ptr<ReadableFakeWebSocketStream> stream( 1465 new ReadableFakeWebSocketStream); 1466 static const InitFrame frames[] = {{FINAL_FRAME, 4, NOT_MASKED, "HELLO"}}; 1467 1468 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1469 set_stream(stream.Pass()); 1470 { 1471 InSequence s; 1472 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1473 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1474 EXPECT_CALL(*event_interface_, 1475 OnDropChannel(kWebSocketErrorProtocolError, _)); 1476 } 1477 1478 CreateChannelAndConnectSuccessfully(); 1479 base::MessageLoop::current()->RunUntilIdle(); 1480 } 1481 1482 // RFC6455 5.4 "Control frames ... MAY be injected in the middle of a 1483 // fragmented message." 1484 TEST_F(WebSocketChannelEventInterfaceTest, ControlFrameInDataMessage) { 1485 scoped_ptr<ReadableFakeWebSocketStream> stream( 1486 new ReadableFakeWebSocketStream); 1487 // We have one message of type Text split into two frames. In the middle is a 1488 // control message of type Pong. 1489 static const InitFrame frames1[] = { 1490 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 1491 NOT_MASKED, "SPLIT "}}; 1492 static const InitFrame frames2[] = { 1493 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, ""}}; 1494 static const InitFrame frames3[] = { 1495 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 1496 NOT_MASKED, "MESSAGE"}}; 1497 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames1); 1498 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames2); 1499 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames3); 1500 set_stream(stream.Pass()); 1501 { 1502 InSequence s; 1503 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1504 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1505 EXPECT_CALL( 1506 *event_interface_, 1507 OnDataFrame( 1508 false, WebSocketFrameHeader::kOpCodeText, AsVector("SPLIT "))); 1509 EXPECT_CALL(*event_interface_, 1510 OnDataFrame(true, 1511 WebSocketFrameHeader::kOpCodeContinuation, 1512 AsVector("MESSAGE"))); 1513 } 1514 1515 CreateChannelAndConnectSuccessfully(); 1516 base::MessageLoop::current()->RunUntilIdle(); 1517 } 1518 1519 // It seems redundant to repeat the entirety of the above test, so just test a 1520 // Pong with NULL data. 1521 TEST_F(WebSocketChannelEventInterfaceTest, PongWithNullData) { 1522 scoped_ptr<ReadableFakeWebSocketStream> stream( 1523 new ReadableFakeWebSocketStream); 1524 static const InitFrame frames[] = { 1525 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, NOT_MASKED, NULL}}; 1526 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1527 set_stream(stream.Pass()); 1528 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1529 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1530 1531 CreateChannelAndConnectSuccessfully(); 1532 base::MessageLoop::current()->RunUntilIdle(); 1533 } 1534 1535 // If a frame has an invalid header, then the connection is closed and 1536 // subsequent frames must not trigger events. 1537 TEST_F(WebSocketChannelEventInterfaceTest, FrameAfterInvalidFrame) { 1538 scoped_ptr<ReadableFakeWebSocketStream> stream( 1539 new ReadableFakeWebSocketStream); 1540 static const InitFrame frames[] = { 1541 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "HELLO"}, 1542 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, NOT_MASKED, " WORLD"}}; 1543 1544 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1545 set_stream(stream.Pass()); 1546 { 1547 InSequence s; 1548 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1549 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1550 EXPECT_CALL(*event_interface_, 1551 OnDropChannel(kWebSocketErrorProtocolError, _)); 1552 } 1553 1554 CreateChannelAndConnectSuccessfully(); 1555 base::MessageLoop::current()->RunUntilIdle(); 1556 } 1557 1558 // If the renderer sends lots of small writes, we don't want to update the quota 1559 // for each one. 1560 TEST_F(WebSocketChannelEventInterfaceTest, SmallWriteDoesntUpdateQuota) { 1561 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1562 { 1563 InSequence s; 1564 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1565 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1566 } 1567 1568 CreateChannelAndConnectSuccessfully(); 1569 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("B")); 1570 } 1571 1572 // If we send enough to go below send_quota_low_water_mask_ we should get our 1573 // quota refreshed. 1574 TEST_F(WebSocketChannelEventInterfaceTest, LargeWriteUpdatesQuota) { 1575 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1576 // We use this checkpoint object to verify that the quota update comes after 1577 // the write. 1578 Checkpoint checkpoint; 1579 { 1580 InSequence s; 1581 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1582 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1583 EXPECT_CALL(checkpoint, Call(1)); 1584 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1585 EXPECT_CALL(checkpoint, Call(2)); 1586 } 1587 1588 CreateChannelAndConnectSuccessfully(); 1589 checkpoint.Call(1); 1590 channel_->SendFrame(true, 1591 WebSocketFrameHeader::kOpCodeText, 1592 std::vector<char>(kDefaultInitialQuota, 'B')); 1593 checkpoint.Call(2); 1594 } 1595 1596 // Verify that our quota actually is refreshed when we are told it is. 1597 TEST_F(WebSocketChannelEventInterfaceTest, QuotaReallyIsRefreshed) { 1598 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1599 Checkpoint checkpoint; 1600 { 1601 InSequence s; 1602 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1603 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1604 EXPECT_CALL(checkpoint, Call(1)); 1605 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1606 EXPECT_CALL(checkpoint, Call(2)); 1607 // If quota was not really refreshed, we would get an OnDropChannel() 1608 // message. 1609 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1610 EXPECT_CALL(checkpoint, Call(3)); 1611 } 1612 1613 CreateChannelAndConnectSuccessfully(); 1614 checkpoint.Call(1); 1615 channel_->SendFrame(true, 1616 WebSocketFrameHeader::kOpCodeText, 1617 std::vector<char>(kDefaultQuotaRefreshTrigger, 'D')); 1618 checkpoint.Call(2); 1619 // We should have received more quota at this point. 1620 channel_->SendFrame(true, 1621 WebSocketFrameHeader::kOpCodeText, 1622 std::vector<char>(kDefaultQuotaRefreshTrigger, 'E')); 1623 checkpoint.Call(3); 1624 } 1625 1626 // If we send more than the available quota then the connection will be closed 1627 // with an error. 1628 TEST_F(WebSocketChannelEventInterfaceTest, WriteOverQuotaIsRejected) { 1629 set_stream(make_scoped_ptr(new WriteableFakeWebSocketStream)); 1630 { 1631 InSequence s; 1632 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1633 EXPECT_CALL(*event_interface_, OnFlowControl(kDefaultInitialQuota)); 1634 EXPECT_CALL(*event_interface_, 1635 OnDropChannel(kWebSocketMuxErrorSendQuotaViolation, _)); 1636 } 1637 1638 CreateChannelAndConnectSuccessfully(); 1639 channel_->SendFrame(true, 1640 WebSocketFrameHeader::kOpCodeText, 1641 std::vector<char>(kDefaultInitialQuota + 1, 'C')); 1642 } 1643 1644 // If a write fails, the channel is dropped. 1645 TEST_F(WebSocketChannelEventInterfaceTest, FailedWrite) { 1646 set_stream(make_scoped_ptr(new UnWriteableFakeWebSocketStream)); 1647 Checkpoint checkpoint; 1648 { 1649 InSequence s; 1650 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1651 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1652 EXPECT_CALL(checkpoint, Call(1)); 1653 EXPECT_CALL(*event_interface_, 1654 OnDropChannel(kWebSocketErrorAbnormalClosure, _)); 1655 EXPECT_CALL(checkpoint, Call(2)); 1656 } 1657 1658 CreateChannelAndConnectSuccessfully(); 1659 checkpoint.Call(1); 1660 1661 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("H")); 1662 checkpoint.Call(2); 1663 } 1664 1665 // OnDropChannel() is called exactly once when StartClosingHandshake() is used. 1666 TEST_F(WebSocketChannelEventInterfaceTest, SendCloseDropsChannel) { 1667 set_stream(make_scoped_ptr(new EchoeyFakeWebSocketStream)); 1668 { 1669 InSequence s; 1670 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1671 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1672 EXPECT_CALL(*event_interface_, 1673 OnDropChannel(kWebSocketNormalClosure, "Fred")); 1674 } 1675 1676 CreateChannelAndConnectSuccessfully(); 1677 1678 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Fred"); 1679 base::MessageLoop::current()->RunUntilIdle(); 1680 } 1681 1682 // OnDropChannel() is only called once when a write() on the socket triggers a 1683 // connection reset. 1684 TEST_F(WebSocketChannelEventInterfaceTest, OnDropChannelCalledOnce) { 1685 set_stream(make_scoped_ptr(new ResetOnWriteFakeWebSocketStream)); 1686 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1687 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1688 1689 EXPECT_CALL(*event_interface_, 1690 OnDropChannel(kWebSocketErrorAbnormalClosure, "Abnormal Closure")) 1691 .Times(1); 1692 1693 CreateChannelAndConnectSuccessfully(); 1694 1695 channel_->SendFrame(true, WebSocketFrameHeader::kOpCodeText, AsVector("yt?")); 1696 base::MessageLoop::current()->RunUntilIdle(); 1697 } 1698 1699 // When the remote server sends a Close frame with an empty payload, 1700 // WebSocketChannel should report code 1005, kWebSocketErrorNoStatusReceived. 1701 TEST_F(WebSocketChannelEventInterfaceTest, CloseWithNoPayloadGivesStatus1005) { 1702 scoped_ptr<ReadableFakeWebSocketStream> stream( 1703 new ReadableFakeWebSocketStream); 1704 static const InitFrame frames[] = { 1705 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; 1706 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1707 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1708 ERR_CONNECTION_CLOSED); 1709 set_stream(stream.Pass()); 1710 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1711 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1712 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1713 EXPECT_CALL(*event_interface_, 1714 OnDropChannel(kWebSocketErrorNoStatusReceived, _)); 1715 1716 CreateChannelAndConnectSuccessfully(); 1717 } 1718 1719 // A version of the above test with NULL payload. 1720 TEST_F(WebSocketChannelEventInterfaceTest, 1721 CloseWithNullPayloadGivesStatus1005) { 1722 scoped_ptr<ReadableFakeWebSocketStream> stream( 1723 new ReadableFakeWebSocketStream); 1724 static const InitFrame frames[] = { 1725 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, NULL}}; 1726 stream->PrepareReadFrames(ReadableFakeWebSocketStream::SYNC, OK, frames); 1727 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1728 ERR_CONNECTION_CLOSED); 1729 set_stream(stream.Pass()); 1730 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1731 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1732 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1733 EXPECT_CALL(*event_interface_, 1734 OnDropChannel(kWebSocketErrorNoStatusReceived, _)); 1735 1736 CreateChannelAndConnectSuccessfully(); 1737 } 1738 1739 // If ReadFrames() returns ERR_WS_PROTOCOL_ERROR, then 1740 // kWebSocketErrorProtocolError must be sent to the renderer. 1741 TEST_F(WebSocketChannelEventInterfaceTest, SyncProtocolErrorGivesStatus1002) { 1742 scoped_ptr<ReadableFakeWebSocketStream> stream( 1743 new ReadableFakeWebSocketStream); 1744 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1745 ERR_WS_PROTOCOL_ERROR); 1746 set_stream(stream.Pass()); 1747 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1748 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1749 1750 EXPECT_CALL(*event_interface_, 1751 OnDropChannel(kWebSocketErrorProtocolError, _)); 1752 1753 CreateChannelAndConnectSuccessfully(); 1754 } 1755 1756 // Async version of above test. 1757 TEST_F(WebSocketChannelEventInterfaceTest, AsyncProtocolErrorGivesStatus1002) { 1758 scoped_ptr<ReadableFakeWebSocketStream> stream( 1759 new ReadableFakeWebSocketStream); 1760 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::ASYNC, 1761 ERR_WS_PROTOCOL_ERROR); 1762 set_stream(stream.Pass()); 1763 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1764 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1765 1766 EXPECT_CALL(*event_interface_, 1767 OnDropChannel(kWebSocketErrorProtocolError, _)); 1768 1769 CreateChannelAndConnectSuccessfully(); 1770 base::MessageLoop::current()->RunUntilIdle(); 1771 } 1772 1773 // The closing handshake times out and sends an OnDropChannel event if no 1774 // response to the client Close message is received. 1775 TEST_F(WebSocketChannelEventInterfaceTest, 1776 ClientInitiatedClosingHandshakeTimesOut) { 1777 scoped_ptr<ReadableFakeWebSocketStream> stream( 1778 new ReadableFakeWebSocketStream); 1779 stream->PrepareReadFramesError(ReadableFakeWebSocketStream::SYNC, 1780 ERR_IO_PENDING); 1781 set_stream(stream.Pass()); 1782 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1783 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1784 // This checkpoint object verifies that the OnDropChannel message comes after 1785 // the timeout. 1786 Checkpoint checkpoint; 1787 TestClosure completion; 1788 { 1789 InSequence s; 1790 EXPECT_CALL(checkpoint, Call(1)); 1791 EXPECT_CALL(*event_interface_, 1792 OnDropChannel(kWebSocketErrorAbnormalClosure, _)) 1793 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); 1794 } 1795 CreateChannelAndConnectSuccessfully(); 1796 // OneShotTimer is not very friendly to testing; there is no apparent way to 1797 // set an expectation on it. Instead the tests need to infer that the timeout 1798 // was fired by the behaviour of the WebSocketChannel object. 1799 channel_->SetClosingHandshakeTimeoutForTesting( 1800 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); 1801 channel_->StartClosingHandshake(kWebSocketNormalClosure, ""); 1802 checkpoint.Call(1); 1803 completion.WaitForResult(); 1804 } 1805 1806 // The closing handshake times out and sends an OnDropChannel event if a Close 1807 // message is received but the connection isn't closed by the remote host. 1808 TEST_F(WebSocketChannelEventInterfaceTest, 1809 ServerInitiatedClosingHandshakeTimesOut) { 1810 scoped_ptr<ReadableFakeWebSocketStream> stream( 1811 new ReadableFakeWebSocketStream); 1812 static const InitFrame frames[] = { 1813 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1814 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 1815 stream->PrepareReadFrames(ReadableFakeWebSocketStream::ASYNC, OK, frames); 1816 set_stream(stream.Pass()); 1817 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 1818 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 1819 Checkpoint checkpoint; 1820 TestClosure completion; 1821 { 1822 InSequence s; 1823 EXPECT_CALL(checkpoint, Call(1)); 1824 EXPECT_CALL(*event_interface_, OnClosingHandshake()); 1825 EXPECT_CALL(*event_interface_, 1826 OnDropChannel(kWebSocketErrorAbnormalClosure, _)) 1827 .WillOnce(InvokeClosureReturnDeleted(completion.closure())); 1828 } 1829 CreateChannelAndConnectSuccessfully(); 1830 channel_->SetClosingHandshakeTimeoutForTesting( 1831 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); 1832 checkpoint.Call(1); 1833 completion.WaitForResult(); 1834 } 1835 1836 // RFC6455 5.1 "a client MUST mask all frames that it sends to the server". 1837 // WebSocketChannel actually only sets the mask bit in the header, it doesn't 1838 // perform masking itself (not all transports actually use masking). 1839 TEST_F(WebSocketChannelStreamTest, SentFramesAreMasked) { 1840 static const InitFrame expected[] = { 1841 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, 1842 MASKED, "NEEDS MASKING"}}; 1843 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1844 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1845 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 1846 .WillOnce(Return(OK)); 1847 1848 CreateChannelAndConnectSuccessfully(); 1849 channel_->SendFrame( 1850 true, WebSocketFrameHeader::kOpCodeText, AsVector("NEEDS MASKING")); 1851 } 1852 1853 // RFC6455 5.5.1 "The application MUST NOT send any more data frames after 1854 // sending a Close frame." 1855 TEST_F(WebSocketChannelStreamTest, NothingIsSentAfterClose) { 1856 static const InitFrame expected[] = { 1857 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1858 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Success")}}; 1859 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1860 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 1861 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 1862 .WillOnce(Return(OK)); 1863 1864 CreateChannelAndConnectSuccessfully(); 1865 channel_->StartClosingHandshake(1000, "Success"); 1866 channel_->SendFrame( 1867 true, WebSocketFrameHeader::kOpCodeText, AsVector("SHOULD BE IGNORED")); 1868 } 1869 1870 // RFC6455 5.5.1 "If an endpoint receives a Close frame and did not previously 1871 // send a Close frame, the endpoint MUST send a Close frame in response." 1872 TEST_F(WebSocketChannelStreamTest, CloseIsEchoedBack) { 1873 static const InitFrame frames[] = { 1874 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1875 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1876 static const InitFrame expected[] = { 1877 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1878 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1879 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1880 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1881 .WillOnce(ReturnFrames(&frames)) 1882 .WillRepeatedly(Return(ERR_IO_PENDING)); 1883 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 1884 .WillOnce(Return(OK)); 1885 1886 CreateChannelAndConnectSuccessfully(); 1887 } 1888 1889 // The converse of the above case; after sending a Close frame, we should not 1890 // send another one. 1891 TEST_F(WebSocketChannelStreamTest, CloseOnlySentOnce) { 1892 static const InitFrame expected[] = { 1893 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1894 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1895 static const InitFrame frames_init[] = { 1896 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1897 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "Close")}}; 1898 1899 // We store the parameters that were passed to ReadFrames() so that we can 1900 // call them explicitly later. 1901 CompletionCallback read_callback; 1902 ScopedVector<WebSocketFrame>* frames = NULL; 1903 1904 // Use a checkpoint to make the ordering of events clearer. 1905 Checkpoint checkpoint; 1906 { 1907 InSequence s; 1908 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1909 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1910 .WillOnce(DoAll(SaveArg<0>(&frames), 1911 SaveArg<1>(&read_callback), 1912 Return(ERR_IO_PENDING))); 1913 EXPECT_CALL(checkpoint, Call(1)); 1914 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 1915 .WillOnce(Return(OK)); 1916 EXPECT_CALL(checkpoint, Call(2)); 1917 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1918 .WillOnce(Return(ERR_IO_PENDING)); 1919 EXPECT_CALL(checkpoint, Call(3)); 1920 // WriteFrames() must not be called again. GoogleMock will ensure that the 1921 // test fails if it is. 1922 } 1923 1924 CreateChannelAndConnectSuccessfully(); 1925 checkpoint.Call(1); 1926 channel_->StartClosingHandshake(kWebSocketNormalClosure, "Close"); 1927 checkpoint.Call(2); 1928 1929 *frames = CreateFrameVector(frames_init); 1930 read_callback.Run(OK); 1931 checkpoint.Call(3); 1932 } 1933 1934 // Invalid close status codes should not be sent on the network. 1935 TEST_F(WebSocketChannelStreamTest, InvalidCloseStatusCodeNotSent) { 1936 static const InitFrame expected[] = { 1937 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1938 MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Error")}}; 1939 1940 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1941 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1942 .WillOnce(Return(ERR_IO_PENDING)); 1943 1944 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); 1945 1946 CreateChannelAndConnectSuccessfully(); 1947 channel_->StartClosingHandshake(999, ""); 1948 } 1949 1950 // A Close frame with a reason longer than 123 bytes cannot be sent on the 1951 // network. 1952 TEST_F(WebSocketChannelStreamTest, LongCloseReasonNotSent) { 1953 static const InitFrame expected[] = { 1954 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 1955 MASKED, CLOSE_DATA(SERVER_ERROR, "Internal Error")}}; 1956 1957 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1958 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1959 .WillOnce(Return(ERR_IO_PENDING)); 1960 1961 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)); 1962 1963 CreateChannelAndConnectSuccessfully(); 1964 channel_->StartClosingHandshake(1000, std::string(124, 'A')); 1965 } 1966 1967 // We generate code 1005, kWebSocketErrorNoStatusReceived, when there is no 1968 // status in the Close message from the other side. Code 1005 is not allowed to 1969 // appear on the wire, so we should not echo it back. See test 1970 // CloseWithNoPayloadGivesStatus1005, above, for confirmation that code 1005 is 1971 // correctly generated internally. 1972 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoed) { 1973 static const InitFrame frames[] = { 1974 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, ""}}; 1975 static const InitFrame expected[] = { 1976 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, ""}}; 1977 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1978 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1979 .WillOnce(ReturnFrames(&frames)) 1980 .WillRepeatedly(Return(ERR_IO_PENDING)); 1981 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 1982 .WillOnce(Return(OK)); 1983 1984 CreateChannelAndConnectSuccessfully(); 1985 } 1986 1987 TEST_F(WebSocketChannelStreamTest, Code1005IsNotEchoedNull) { 1988 static const InitFrame frames[] = { 1989 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, NOT_MASKED, NULL}}; 1990 static const InitFrame expected[] = { 1991 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, MASKED, ""}}; 1992 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 1993 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 1994 .WillOnce(ReturnFrames(&frames)) 1995 .WillRepeatedly(Return(ERR_IO_PENDING)); 1996 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 1997 .WillOnce(Return(OK)); 1998 1999 CreateChannelAndConnectSuccessfully(); 2000 } 2001 2002 // RFC6455 5.5.2 "Upon receipt of a Ping frame, an endpoint MUST send a Pong 2003 // frame in response" 2004 // 5.5.3 "A Pong frame sent in response to a Ping frame must have identical 2005 // "Application data" as found in the message body of the Ping frame being 2006 // replied to." 2007 TEST_F(WebSocketChannelStreamTest, PingRepliedWithPong) { 2008 static const InitFrame frames[] = { 2009 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, 2010 NOT_MASKED, "Application data"}}; 2011 static const InitFrame expected[] = { 2012 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, 2013 MASKED, "Application data"}}; 2014 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2015 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2016 .WillOnce(ReturnFrames(&frames)) 2017 .WillRepeatedly(Return(ERR_IO_PENDING)); 2018 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2019 .WillOnce(Return(OK)); 2020 2021 CreateChannelAndConnectSuccessfully(); 2022 } 2023 2024 // A ping with a NULL payload should be responded to with a Pong with an empty 2025 // payload. 2026 TEST_F(WebSocketChannelStreamTest, NullPingRepliedWithEmptyPong) { 2027 static const InitFrame frames[] = { 2028 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, NOT_MASKED, NULL}}; 2029 static const InitFrame expected[] = { 2030 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, MASKED, ""}}; 2031 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2032 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2033 .WillOnce(ReturnFrames(&frames)) 2034 .WillRepeatedly(Return(ERR_IO_PENDING)); 2035 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2036 .WillOnce(Return(OK)); 2037 2038 CreateChannelAndConnectSuccessfully(); 2039 } 2040 2041 TEST_F(WebSocketChannelStreamTest, PongInTheMiddleOfDataMessage) { 2042 static const InitFrame frames[] = { 2043 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, 2044 NOT_MASKED, "Application data"}}; 2045 static const InitFrame expected1[] = { 2046 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; 2047 static const InitFrame expected2[] = { 2048 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePong, 2049 MASKED, "Application data"}}; 2050 static const InitFrame expected3[] = { 2051 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeContinuation, 2052 MASKED, "World"}}; 2053 ScopedVector<WebSocketFrame>* read_frames; 2054 CompletionCallback read_callback; 2055 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2056 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2057 .WillOnce(DoAll(SaveArg<0>(&read_frames), 2058 SaveArg<1>(&read_callback), 2059 Return(ERR_IO_PENDING))) 2060 .WillRepeatedly(Return(ERR_IO_PENDING)); 2061 { 2062 InSequence s; 2063 2064 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) 2065 .WillOnce(Return(OK)); 2066 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) 2067 .WillOnce(Return(OK)); 2068 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected3), _)) 2069 .WillOnce(Return(OK)); 2070 } 2071 2072 CreateChannelAndConnectSuccessfully(); 2073 channel_->SendFrame( 2074 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); 2075 *read_frames = CreateFrameVector(frames); 2076 read_callback.Run(OK); 2077 channel_->SendFrame( 2078 true, WebSocketFrameHeader::kOpCodeContinuation, AsVector("World")); 2079 } 2080 2081 // WriteFrames() may not be called until the previous write has completed. 2082 // WebSocketChannel must buffer writes that happen in the meantime. 2083 TEST_F(WebSocketChannelStreamTest, WriteFramesOneAtATime) { 2084 static const InitFrame expected1[] = { 2085 {NOT_FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "Hello "}}; 2086 static const InitFrame expected2[] = { 2087 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "World"}}; 2088 CompletionCallback write_callback; 2089 Checkpoint checkpoint; 2090 2091 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2092 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2093 { 2094 InSequence s; 2095 EXPECT_CALL(checkpoint, Call(1)); 2096 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) 2097 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); 2098 EXPECT_CALL(checkpoint, Call(2)); 2099 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) 2100 .WillOnce(Return(ERR_IO_PENDING)); 2101 EXPECT_CALL(checkpoint, Call(3)); 2102 } 2103 2104 CreateChannelAndConnectSuccessfully(); 2105 checkpoint.Call(1); 2106 channel_->SendFrame( 2107 false, WebSocketFrameHeader::kOpCodeText, AsVector("Hello ")); 2108 channel_->SendFrame( 2109 true, WebSocketFrameHeader::kOpCodeText, AsVector("World")); 2110 checkpoint.Call(2); 2111 write_callback.Run(OK); 2112 checkpoint.Call(3); 2113 } 2114 2115 // WebSocketChannel must buffer frames while it is waiting for a write to 2116 // complete, and then send them in a single batch. The batching behaviour is 2117 // important to get good throughput in the "many small messages" case. 2118 TEST_F(WebSocketChannelStreamTest, WaitingMessagesAreBatched) { 2119 static const char input_letters[] = "Hello"; 2120 static const InitFrame expected1[] = { 2121 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "H"}}; 2122 static const InitFrame expected2[] = { 2123 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "e"}, 2124 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"}, 2125 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "l"}, 2126 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeText, MASKED, "o"}}; 2127 CompletionCallback write_callback; 2128 2129 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2130 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2131 { 2132 InSequence s; 2133 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected1), _)) 2134 .WillOnce(DoAll(SaveArg<1>(&write_callback), Return(ERR_IO_PENDING))); 2135 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected2), _)) 2136 .WillOnce(Return(ERR_IO_PENDING)); 2137 } 2138 2139 CreateChannelAndConnectSuccessfully(); 2140 for (size_t i = 0; i < strlen(input_letters); ++i) { 2141 channel_->SendFrame(true, 2142 WebSocketFrameHeader::kOpCodeText, 2143 std::vector<char>(1, input_letters[i])); 2144 } 2145 write_callback.Run(OK); 2146 } 2147 2148 // When the renderer sends more on a channel than it has quota for, then we send 2149 // a kWebSocketMuxErrorSendQuotaViolation status code (from the draft websocket 2150 // mux specification) back to the renderer. This should not be sent to the 2151 // remote server, which may not even implement the mux specification, and could 2152 // even be using a different extension which uses that code to mean something 2153 // else. 2154 TEST_F(WebSocketChannelStreamTest, MuxErrorIsNotSentToStream) { 2155 static const InitFrame expected[] = { 2156 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2157 MASKED, CLOSE_DATA(GOING_AWAY, "Internal Error")}}; 2158 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2159 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2160 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2161 .WillOnce(Return(OK)); 2162 EXPECT_CALL(*mock_stream_, Close()); 2163 2164 CreateChannelAndConnectSuccessfully(); 2165 channel_->SendFrame(true, 2166 WebSocketFrameHeader::kOpCodeText, 2167 std::vector<char>(kDefaultInitialQuota + 1, 'C')); 2168 } 2169 2170 // For convenience, most of these tests use Text frames. However, the WebSocket 2171 // protocol also has Binary frames and those need to be 8-bit clean. For the 2172 // sake of completeness, this test verifies that they are. 2173 TEST_F(WebSocketChannelStreamTest, WrittenBinaryFramesAre8BitClean) { 2174 ScopedVector<WebSocketFrame>* frames = NULL; 2175 2176 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2177 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)).WillOnce(Return(ERR_IO_PENDING)); 2178 EXPECT_CALL(*mock_stream_, WriteFrames(_, _)) 2179 .WillOnce(DoAll(SaveArg<0>(&frames), Return(ERR_IO_PENDING))); 2180 2181 CreateChannelAndConnectSuccessfully(); 2182 channel_->SendFrame( 2183 true, 2184 WebSocketFrameHeader::kOpCodeBinary, 2185 std::vector<char>(kBinaryBlob, kBinaryBlob + kBinaryBlobSize)); 2186 ASSERT_TRUE(frames != NULL); 2187 ASSERT_EQ(1U, frames->size()); 2188 const WebSocketFrame* out_frame = (*frames)[0]; 2189 EXPECT_EQ(kBinaryBlobSize, out_frame->header.payload_length); 2190 ASSERT_TRUE(out_frame->data); 2191 EXPECT_EQ(0, memcmp(kBinaryBlob, out_frame->data->data(), kBinaryBlobSize)); 2192 } 2193 2194 // Test the read path for 8-bit cleanliness as well. 2195 TEST_F(WebSocketChannelEventInterfaceTest, ReadBinaryFramesAre8BitClean) { 2196 scoped_ptr<WebSocketFrame> frame( 2197 new WebSocketFrame(WebSocketFrameHeader::kOpCodeBinary)); 2198 WebSocketFrameHeader& frame_header = frame->header; 2199 frame_header.final = true; 2200 frame_header.payload_length = kBinaryBlobSize; 2201 frame->data = new IOBuffer(kBinaryBlobSize); 2202 memcpy(frame->data->data(), kBinaryBlob, kBinaryBlobSize); 2203 ScopedVector<WebSocketFrame> frames; 2204 frames.push_back(frame.release()); 2205 scoped_ptr<ReadableFakeWebSocketStream> stream( 2206 new ReadableFakeWebSocketStream); 2207 stream->PrepareRawReadFrames( 2208 ReadableFakeWebSocketStream::SYNC, OK, frames.Pass()); 2209 set_stream(stream.Pass()); 2210 EXPECT_CALL(*event_interface_, OnAddChannelResponse(false, _)); 2211 EXPECT_CALL(*event_interface_, OnFlowControl(_)); 2212 EXPECT_CALL(*event_interface_, 2213 OnDataFrame(true, 2214 WebSocketFrameHeader::kOpCodeBinary, 2215 std::vector<char>(kBinaryBlob, 2216 kBinaryBlob + kBinaryBlobSize))); 2217 2218 CreateChannelAndConnectSuccessfully(); 2219 } 2220 2221 // If we receive another frame after Close, it is not valid. It is not 2222 // completely clear what behaviour is required from the standard in this case, 2223 // but the current implementation fails the connection. Since a Close has 2224 // already been sent, this just means closing the connection. 2225 TEST_F(WebSocketChannelStreamTest, PingAfterCloseIsRejected) { 2226 static const InitFrame frames[] = { 2227 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2228 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}, 2229 {FINAL_FRAME, WebSocketFrameHeader::kOpCodePing, 2230 NOT_MASKED, "Ping body"}}; 2231 static const InitFrame expected[] = { 2232 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2233 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2234 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2235 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2236 .WillOnce(ReturnFrames(&frames)) 2237 .WillRepeatedly(Return(ERR_IO_PENDING)); 2238 { 2239 // We only need to verify the relative order of WriteFrames() and 2240 // Close(). The current implementation calls WriteFrames() for the Close 2241 // frame before calling ReadFrames() again, but that is an implementation 2242 // detail and better not to consider required behaviour. 2243 InSequence s; 2244 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2245 .WillOnce(Return(OK)); 2246 EXPECT_CALL(*mock_stream_, Close()).Times(1); 2247 } 2248 2249 CreateChannelAndConnectSuccessfully(); 2250 } 2251 2252 // A protocol error from the remote server should result in a close frame with 2253 // status 1002, followed by the connection closing. 2254 TEST_F(WebSocketChannelStreamTest, ProtocolError) { 2255 static const InitFrame expected[] = { 2256 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2257 MASKED, CLOSE_DATA(PROTOCOL_ERROR, "WebSocket Protocol Error")}}; 2258 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2259 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2260 .WillOnce(Return(ERR_WS_PROTOCOL_ERROR)); 2261 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2262 .WillOnce(Return(OK)); 2263 EXPECT_CALL(*mock_stream_, Close()); 2264 2265 CreateChannelAndConnectSuccessfully(); 2266 } 2267 2268 // Set the closing handshake timeout to a very tiny value before connecting. 2269 class WebSocketChannelStreamTimeoutTest : public WebSocketChannelStreamTest { 2270 protected: 2271 WebSocketChannelStreamTimeoutTest() {} 2272 2273 virtual void CreateChannelAndConnectSuccessfully() OVERRIDE { 2274 set_stream(mock_stream_.Pass()); 2275 CreateChannelAndConnect(); 2276 channel_->SetClosingHandshakeTimeoutForTesting( 2277 TimeDelta::FromMilliseconds(kVeryTinyTimeoutMillis)); 2278 connect_data_.creator.connect_delegate->OnSuccess(stream_.Pass()); 2279 } 2280 }; 2281 2282 // In this case the server initiates the closing handshake with a Close 2283 // message. WebSocketChannel responds with a matching Close message, and waits 2284 // for the server to close the TCP/IP connection. The server never closes the 2285 // connection, so the closing handshake times out and WebSocketChannel closes 2286 // the connection itself. 2287 TEST_F(WebSocketChannelStreamTimeoutTest, ServerInitiatedCloseTimesOut) { 2288 static const InitFrame frames[] = { 2289 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2290 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2291 static const InitFrame expected[] = { 2292 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2293 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2294 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2295 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2296 .WillOnce(ReturnFrames(&frames)) 2297 .WillRepeatedly(Return(ERR_IO_PENDING)); 2298 Checkpoint checkpoint; 2299 TestClosure completion; 2300 { 2301 InSequence s; 2302 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2303 .WillOnce(Return(OK)); 2304 EXPECT_CALL(checkpoint, Call(1)); 2305 EXPECT_CALL(*mock_stream_, Close()) 2306 .WillOnce(InvokeClosure(completion.closure())); 2307 } 2308 2309 CreateChannelAndConnectSuccessfully(); 2310 checkpoint.Call(1); 2311 completion.WaitForResult(); 2312 } 2313 2314 // In this case the client initiates the closing handshake by sending a Close 2315 // message. WebSocketChannel waits for a Close message in response from the 2316 // server. The server never responds to the Close message, so the closing 2317 // handshake times out and WebSocketChannel closes the connection. 2318 TEST_F(WebSocketChannelStreamTimeoutTest, ClientInitiatedCloseTimesOut) { 2319 static const InitFrame expected[] = { 2320 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2321 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2322 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2323 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2324 .WillRepeatedly(Return(ERR_IO_PENDING)); 2325 TestClosure completion; 2326 { 2327 InSequence s; 2328 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2329 .WillOnce(Return(OK)); 2330 EXPECT_CALL(*mock_stream_, Close()) 2331 .WillOnce(InvokeClosure(completion.closure())); 2332 } 2333 2334 CreateChannelAndConnectSuccessfully(); 2335 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); 2336 completion.WaitForResult(); 2337 } 2338 2339 // In this case the client initiates the closing handshake and the server 2340 // responds with a matching Close message. WebSocketChannel waits for the server 2341 // to close the TCP/IP connection, but it never does. The closing handshake 2342 // times out and WebSocketChannel closes the connection. 2343 TEST_F(WebSocketChannelStreamTimeoutTest, ConnectionCloseTimesOut) { 2344 static const InitFrame expected[] = { 2345 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2346 MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2347 static const InitFrame frames[] = { 2348 {FINAL_FRAME, WebSocketFrameHeader::kOpCodeClose, 2349 NOT_MASKED, CLOSE_DATA(NORMAL_CLOSURE, "OK")}}; 2350 EXPECT_CALL(*mock_stream_, GetSubProtocol()).Times(AnyNumber()); 2351 TestClosure completion; 2352 ScopedVector<WebSocketFrame>* read_frames = NULL; 2353 CompletionCallback read_callback; 2354 { 2355 InSequence s; 2356 // Copy the arguments to ReadFrames so that the test can call the callback 2357 // after it has send the close message. 2358 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2359 .WillOnce(DoAll(SaveArg<0>(&read_frames), 2360 SaveArg<1>(&read_callback), 2361 Return(ERR_IO_PENDING))); 2362 // The first real event that happens is the client sending the Close 2363 // message. 2364 EXPECT_CALL(*mock_stream_, WriteFrames(EqualsFrames(expected), _)) 2365 .WillOnce(Return(OK)); 2366 // The |read_frames| callback is called (from this test case) at this 2367 // point. ReadFrames is called again by WebSocketChannel, waiting for 2368 // ERR_CONNECTION_CLOSED. 2369 EXPECT_CALL(*mock_stream_, ReadFrames(_, _)) 2370 .WillOnce(Return(ERR_IO_PENDING)); 2371 // The timeout happens and so WebSocketChannel closes the stream. 2372 EXPECT_CALL(*mock_stream_, Close()) 2373 .WillOnce(InvokeClosure(completion.closure())); 2374 } 2375 2376 CreateChannelAndConnectSuccessfully(); 2377 channel_->StartClosingHandshake(kWebSocketNormalClosure, "OK"); 2378 ASSERT_TRUE(read_frames); 2379 // Provide the "Close" message from the server. 2380 *read_frames = CreateFrameVector(frames); 2381 read_callback.Run(OK); 2382 completion.WaitForResult(); 2383 } 2384 2385 } // namespace 2386 } // namespace net 2387