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