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