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