1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/websockets/websocket_deflate_stream.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <iterator>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/bind.h"
16 #include "base/callback_helpers.h"
17 #include "base/containers/circular_deque.h"
18 #include "base/macros.h"
19 #include "base/memory/ptr_util.h"
20 #include "base/memory/scoped_refptr.h"
21 #include "base/test/mock_callback.h"
22 #include "net/base/io_buffer.h"
23 #include "net/base/net_errors.h"
24 #include "net/test/gtest_util.h"
25 #include "net/websockets/websocket_deflate_parameters.h"
26 #include "net/websockets/websocket_deflate_predictor.h"
27 #include "net/websockets/websocket_deflater.h"
28 #include "net/websockets/websocket_frame.h"
29 #include "net/websockets/websocket_inflater.h"
30 #include "net/websockets/websocket_stream.h"
31 #include "net/websockets/websocket_test_util.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 
35 using net::test::IsError;
36 using net::test::IsOk;
37 
38 namespace net {
39 namespace {
40 
41 using ::testing::_;
42 using ::testing::InSequence;
43 using ::testing::Invoke;
44 using ::testing::Return;
45 
46 typedef uint32_t FrameFlag;
47 const FrameFlag kNoFlag = 0;
48 const FrameFlag kFinal = 1;
49 const FrameFlag kReserved1 = 2;
50 // We don't define values for other flags because we don't need them.
51 
52 // The value must equal to the value of the corresponding
53 // constant in websocket_deflate_stream.cc
54 const size_t kChunkSize = 4 * 1024;
55 const int kWindowBits = 15;
56 
ToString(IOBufferWithSize * buffer)57 std::string ToString(IOBufferWithSize* buffer) {
58   return std::string(buffer->data(), buffer->size());
59 }
60 
ToString(const scoped_refptr<IOBufferWithSize> & buffer)61 std::string ToString(const scoped_refptr<IOBufferWithSize>& buffer) {
62   return ToString(buffer.get());
63 }
64 
ToString(const WebSocketFrame * frame)65 std::string ToString(const WebSocketFrame* frame) {
66   return frame->payload
67              ? std::string(frame->payload, frame->header.payload_length)
68              : "";
69 }
70 
ToString(const std::unique_ptr<WebSocketFrame> & frame)71 std::string ToString(const std::unique_ptr<WebSocketFrame>& frame) {
72   return ToString(frame.get());
73 }
74 
75 class MockWebSocketStream : public WebSocketStream {
76  public:
77   // GMock cannot save or forward move-only types like CompletionOnceCallback,
78   // therefore they have to be converted into a copyable type like
79   // CompletionRepeatingCallback.
ReadFrames(std::vector<std::unique_ptr<WebSocketFrame>> * frames,CompletionOnceCallback callback)80   int ReadFrames(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
81                  CompletionOnceCallback callback) {
82     return ReadFramesInternal(
83         frames, callback ? base::AdaptCallbackForRepeating(std::move(callback))
84                          : CompletionRepeatingCallback());
85   }
WriteFrames(std::vector<std::unique_ptr<WebSocketFrame>> * frames,CompletionOnceCallback callback)86   int WriteFrames(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
87                   CompletionOnceCallback callback) {
88     return WriteFramesInternal(
89         frames, callback ? base::AdaptCallbackForRepeating(std::move(callback))
90                          : CompletionRepeatingCallback());
91   }
92 
93   MOCK_METHOD2(ReadFramesInternal,
94                int(std::vector<std::unique_ptr<WebSocketFrame>>*,
95                    const CompletionRepeatingCallback&));
96   MOCK_METHOD2(WriteFramesInternal,
97                int(std::vector<std::unique_ptr<WebSocketFrame>>*,
98                    const CompletionRepeatingCallback&));
99 
100   MOCK_METHOD0(Close, void());
101   MOCK_CONST_METHOD0(GetSubProtocol, std::string());
102   MOCK_CONST_METHOD0(GetExtensions, std::string());
103 };
104 
105 // This mock class relies on some assumptions.
106 //  - RecordInputDataFrame is called after the corresponding WriteFrames
107 //    call.
108 //  - RecordWrittenDataFrame is called before writing the frame.
109 class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor {
110  public:
WebSocketDeflatePredictorMock()111   WebSocketDeflatePredictorMock() : result_(DEFLATE) {}
~WebSocketDeflatePredictorMock()112   ~WebSocketDeflatePredictorMock() override {
113     // Verify whether all expectaions are consumed.
114     if (!frames_to_be_input_.empty()) {
115       ADD_FAILURE() << "There are missing frames to be input.";
116       return;
117     }
118     if (!frames_written_.empty()) {
119       ADD_FAILURE() << "There are extra written frames.";
120       return;
121     }
122   }
123 
124   // WebSocketDeflatePredictor functions.
Predict(const std::vector<std::unique_ptr<WebSocketFrame>> & frames,size_t frame_index)125   Result Predict(const std::vector<std::unique_ptr<WebSocketFrame>>& frames,
126                  size_t frame_index) override {
127     return result_;
128   }
RecordInputDataFrame(const WebSocketFrame * frame)129   void RecordInputDataFrame(const WebSocketFrame* frame) override {
130     if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
131       ADD_FAILURE() << "Control frames should not be recorded.";
132       return;
133     }
134     if (frame->header.reserved1) {
135       ADD_FAILURE() << "Input frame may not be compressed.";
136       return;
137     }
138     if (frames_to_be_input_.empty()) {
139       ADD_FAILURE() << "Unexpected input data frame";
140       return;
141     }
142     if (frame != frames_to_be_input_.front()) {
143       ADD_FAILURE() << "Input data frame does not match the expectation.";
144       return;
145     }
146     frames_to_be_input_.pop_front();
147   }
RecordWrittenDataFrame(const WebSocketFrame * frame)148   void RecordWrittenDataFrame(const WebSocketFrame* frame) override {
149     if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
150       ADD_FAILURE() << "Control frames should not be recorded.";
151       return;
152     }
153     frames_written_.push_back(frame);
154   }
155 
156   // Sets |result_| for the |Predict| return value.
set_result(Result result)157   void set_result(Result result) { result_ = result; }
158 
159   // Adds |frame| as an expectation of future |RecordInputDataFrame| call.
AddFrameToBeInput(const WebSocketFrame * frame)160   void AddFrameToBeInput(const WebSocketFrame* frame) {
161     if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
162       return;
163     frames_to_be_input_.push_back(frame);
164   }
165   // Verifies that |frame| is recorded in order.
VerifySentFrame(const WebSocketFrame * frame)166   void VerifySentFrame(const WebSocketFrame* frame) {
167     if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
168       return;
169     if (frames_written_.empty()) {
170       ADD_FAILURE() << "There are missing frames to be written.";
171       return;
172     }
173     if (frame != frames_written_.front()) {
174       ADD_FAILURE() << "Written data frame does not match the expectation.";
175       return;
176     }
177     frames_written_.pop_front();
178   }
AddFramesToBeInput(const std::vector<std::unique_ptr<WebSocketFrame>> & frames)179   void AddFramesToBeInput(
180       const std::vector<std::unique_ptr<WebSocketFrame>>& frames) {
181     for (size_t i = 0; i < frames.size(); ++i)
182       AddFrameToBeInput(frames[i].get());
183   }
VerifySentFrames(const std::vector<std::unique_ptr<WebSocketFrame>> & frames)184   void VerifySentFrames(
185       const std::vector<std::unique_ptr<WebSocketFrame>>& frames) {
186     for (size_t i = 0; i < frames.size(); ++i)
187       VerifySentFrame(frames[i].get());
188   }
189   // Call this method in order to disable checks in the destructor when
190   // WriteFrames fails.
Clear()191   void Clear() {
192     frames_to_be_input_.clear();
193     frames_written_.clear();
194   }
195 
196  private:
197   Result result_;
198   // Data frames which will be recorded by |RecordInputFrames|.
199   // Pushed by |AddFrameToBeInput| and popped and verified by
200   // |RecordInputFrames|.
201   base::circular_deque<const WebSocketFrame*> frames_to_be_input_;
202   // Data frames recorded by |RecordWrittenFrames|.
203   // Pushed by |RecordWrittenFrames| and popped and verified by
204   // |VerifySentFrame|.
205   base::circular_deque<const WebSocketFrame*> frames_written_;
206 
207   DISALLOW_COPY_AND_ASSIGN(WebSocketDeflatePredictorMock);
208 };
209 
210 class WebSocketDeflateStreamTest : public ::testing::Test {
211  public:
WebSocketDeflateStreamTest()212   WebSocketDeflateStreamTest() : mock_stream_(nullptr), predictor_(nullptr) {}
213   ~WebSocketDeflateStreamTest() override = default;
214 
SetUp()215   void SetUp() override {
216     Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, kWindowBits);
217   }
218 
219  protected:
220   // Initialize deflate_stream_ with the given parameters.
Initialize(WebSocketDeflater::ContextTakeOverMode mode,int window_bits)221   void Initialize(WebSocketDeflater::ContextTakeOverMode mode,
222                   int window_bits) {
223     WebSocketDeflateParameters parameters;
224     if (mode == WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT) {
225       parameters.SetClientNoContextTakeOver();
226     }
227     parameters.SetClientMaxWindowBits(window_bits);
228     mock_stream_ = new testing::StrictMock<MockWebSocketStream>;
229     predictor_ = new WebSocketDeflatePredictorMock;
230     deflate_stream_ = std::make_unique<WebSocketDeflateStream>(
231         base::WrapUnique(mock_stream_), parameters,
232         base::WrapUnique(predictor_));
233   }
234 
AppendTo(std::vector<std::unique_ptr<WebSocketFrame>> * frames,WebSocketFrameHeader::OpCode opcode,FrameFlag flag)235   void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
236                 WebSocketFrameHeader::OpCode opcode,
237                 FrameFlag flag) {
238     auto frame = std::make_unique<WebSocketFrame>(opcode);
239     frame->header.final = (flag & kFinal);
240     frame->header.reserved1 = (flag & kReserved1);
241     frames->push_back(std::move(frame));
242   }
243 
AppendTo(std::vector<std::unique_ptr<WebSocketFrame>> * frames,WebSocketFrameHeader::OpCode opcode,FrameFlag flag,const std::string & data)244   void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
245                 WebSocketFrameHeader::OpCode opcode,
246                 FrameFlag flag,
247                 const std::string& data) {
248     auto frame = std::make_unique<WebSocketFrame>(opcode);
249     frame->header.final = (flag & kFinal);
250     frame->header.reserved1 = (flag & kReserved1);
251     auto buffer = std::make_unique<char[]>(data.size());
252     memcpy(buffer.get(), data.c_str(), data.size());
253     frame->payload = buffer.get();
254     data_buffers.push_back(std::move(buffer));
255     frame->header.payload_length = data.size();
256     frames->push_back(std::move(frame));
257   }
258 
259   std::unique_ptr<WebSocketDeflateStream> deflate_stream_;
260   // Owned by |deflate_stream_|.
261   MockWebSocketStream* mock_stream_;
262   // Owned by |deflate_stream_|.
263   WebSocketDeflatePredictorMock* predictor_;
264 
265   // TODO(yoichio): Make this type std::vector<std::string>.
266   std::vector<std::unique_ptr<const char[]>> data_buffers;
267 };
268 
269 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at
270 // websocket_deflater_test.cc, we have only a few tests for this configuration
271 // here.
272 class WebSocketDeflateStreamWithDoNotTakeOverContextTest
273     : public WebSocketDeflateStreamTest {
274  public:
275   WebSocketDeflateStreamWithDoNotTakeOverContextTest() = default;
276   ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() override = default;
277 
SetUp()278   void SetUp() override {
279     Initialize(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT, kWindowBits);
280   }
281 };
282 
283 class WebSocketDeflateStreamWithClientWindowBitsTest
284     : public WebSocketDeflateStreamTest {
285  public:
286   WebSocketDeflateStreamWithClientWindowBitsTest() = default;
287   ~WebSocketDeflateStreamWithClientWindowBitsTest() override = default;
288 
289   // Overridden to postpone the call to Initialize().
SetUp()290   void SetUp() override {}
291 
292   // This needs to be called explicitly from the tests.
SetUpWithWindowBits(int window_bits)293   void SetUpWithWindowBits(int window_bits) {
294     Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, window_bits);
295   }
296 
297   // Add a frame which will be compressed to a smaller size if the window
298   // size is large enough.
AddCompressibleFrameString()299   void AddCompressibleFrameString() {
300     const std::string word = "Chromium";
301     const std::string payload = word + std::string(256, 'a') + word;
302     AppendTo(&frames_, WebSocketFrameHeader::kOpCodeText, kFinal, payload);
303     predictor_->AddFramesToBeInput(frames_);
304   }
305 
306  protected:
307   std::vector<std::unique_ptr<WebSocketFrame>> frames_;
308 };
309 
310 // ReadFrameStub is a stub for WebSocketStream::ReadFrames.
311 // It returns |result_| and |frames_to_output_| to the caller and
312 // saves parameters to |frames_passed_| and |callback_|.
313 class ReadFramesStub {
314  public:
ReadFramesStub(int result)315   explicit ReadFramesStub(int result) : result_(result) {}
316 
ReadFramesStub(int result,std::vector<std::unique_ptr<WebSocketFrame>> * frames_to_output)317   ReadFramesStub(int result,
318                  std::vector<std::unique_ptr<WebSocketFrame>>* frames_to_output)
319       : result_(result) {
320     frames_to_output_.swap(*frames_to_output);
321   }
322 
Call(std::vector<std::unique_ptr<WebSocketFrame>> * frames,const CompletionRepeatingCallback & callback)323   int Call(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
324            const CompletionRepeatingCallback& callback) {
325     DCHECK(frames->empty());
326     frames_passed_ = frames;
327     callback_ = callback;
328     frames->swap(frames_to_output_);
329     return result_;
330   }
331 
result() const332   int result() const { return result_; }
callback() const333   const CompletionRepeatingCallback& callback() const { return callback_; }
frames_passed()334   std::vector<std::unique_ptr<WebSocketFrame>>* frames_passed() {
335     return frames_passed_;
336   }
337 
338  private:
339   int result_;
340   CompletionRepeatingCallback callback_;
341   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output_;
342   std::vector<std::unique_ptr<WebSocketFrame>>* frames_passed_;
343 };
344 
345 // WriteFramesStub is a stub for WebSocketStream::WriteFrames.
346 // It returns |result_| and |frames_| to the caller and
347 // saves |callback| parameter to |callback_|.
348 class WriteFramesStub {
349  public:
WriteFramesStub(WebSocketDeflatePredictorMock * predictor,int result)350   explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor,
351                            int result)
352       : result_(result), predictor_(predictor) {}
353 
Call(std::vector<std::unique_ptr<WebSocketFrame>> * frames,const CompletionRepeatingCallback & callback)354   int Call(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
355            const CompletionRepeatingCallback& callback) {
356     frames_.insert(frames_.end(), std::make_move_iterator(frames->begin()),
357                    std::make_move_iterator(frames->end()));
358     frames->clear();
359     callback_ = callback;
360     predictor_->VerifySentFrames(frames_);
361     return result_;
362   }
363 
result() const364   int result() const { return result_; }
callback() const365   const CompletionRepeatingCallback& callback() const { return callback_; }
frames()366   std::vector<std::unique_ptr<WebSocketFrame>>* frames() { return &frames_; }
367 
368  private:
369   int result_;
370   CompletionRepeatingCallback callback_;
371   std::vector<std::unique_ptr<WebSocketFrame>> frames_;
372   WebSocketDeflatePredictorMock* predictor_;
373 };
374 
TEST_F(WebSocketDeflateStreamTest,ReadFailedImmediately)375 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
376   std::vector<std::unique_ptr<WebSocketFrame>> frames;
377   {
378     InSequence s;
379     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
380         .WillOnce(Return(ERR_FAILED));
381   }
382   EXPECT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
383               IsError(ERR_FAILED));
384 }
385 
TEST_F(WebSocketDeflateStreamTest,ReadUncompressedFrameImmediately)386 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
387   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
388   AppendTo(&frames_to_output,
389            WebSocketFrameHeader::kOpCodeText,
390            kFinal,
391            "hello");
392   ReadFramesStub stub(OK, &frames_to_output);
393   std::vector<std::unique_ptr<WebSocketFrame>> frames;
394 
395   {
396     InSequence s;
397     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
398         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
399   }
400   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
401               IsOk());
402   ASSERT_EQ(1u, frames.size());
403   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
404   EXPECT_TRUE(frames[0]->header.final);
405   EXPECT_FALSE(frames[0]->header.reserved1);
406   EXPECT_EQ("hello", ToString(frames[0]));
407 }
408 
TEST_F(WebSocketDeflateStreamTest,ReadUncompressedFrameAsync)409 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
410   ReadFramesStub stub(ERR_IO_PENDING);
411   std::vector<std::unique_ptr<WebSocketFrame>> frames;
412   base::MockCallback<CompletionOnceCallback> mock_callback;
413   base::MockCallback<base::OnceClosure> checkpoint;
414 
415   {
416     InSequence s;
417     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
418         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
419     EXPECT_CALL(checkpoint, Run());
420     EXPECT_CALL(mock_callback, Run(OK));
421   }
422   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
423               IsError(ERR_IO_PENDING));
424   ASSERT_EQ(0u, frames.size());
425 
426   checkpoint.Run();
427 
428   AppendTo(stub.frames_passed(),
429            WebSocketFrameHeader::kOpCodeText,
430            kFinal,
431            "hello");
432   stub.callback().Run(OK);
433   ASSERT_EQ(1u, frames.size());
434   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
435   EXPECT_TRUE(frames[0]->header.final);
436   EXPECT_FALSE(frames[0]->header.reserved1);
437   EXPECT_EQ("hello", ToString(frames[0]));
438 }
439 
TEST_F(WebSocketDeflateStreamTest,ReadFailedAsync)440 TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
441   ReadFramesStub stub(ERR_IO_PENDING);
442   std::vector<std::unique_ptr<WebSocketFrame>> frames;
443   base::MockCallback<CompletionOnceCallback> mock_callback;
444   base::MockCallback<base::OnceClosure> checkpoint;
445 
446   {
447     InSequence s;
448     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
449         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
450     EXPECT_CALL(checkpoint, Run());
451     EXPECT_CALL(mock_callback, Run(ERR_FAILED));
452   }
453   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
454               IsError(ERR_IO_PENDING));
455   ASSERT_EQ(0u, frames.size());
456 
457   checkpoint.Run();
458 
459   AppendTo(stub.frames_passed(),
460            WebSocketFrameHeader::kOpCodeText,
461            kFinal,
462            "hello");
463   stub.callback().Run(ERR_FAILED);
464   ASSERT_EQ(0u, frames.size());
465 }
466 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedFrameImmediately)467 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) {
468   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
469   AppendTo(&frames_to_output,
470            WebSocketFrameHeader::kOpCodeText,
471            kFinal | kReserved1,
472            std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
473   ReadFramesStub stub(OK, &frames_to_output);
474   std::vector<std::unique_ptr<WebSocketFrame>> frames;
475   {
476     InSequence s;
477     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
478         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
479   }
480   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
481               IsOk());
482   ASSERT_EQ(1u, frames.size());
483   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
484   EXPECT_TRUE(frames[0]->header.final);
485   EXPECT_FALSE(frames[0]->header.reserved1);
486   EXPECT_EQ("Hello", ToString(frames[0]));
487 }
488 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedFrameAsync)489 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) {
490   ReadFramesStub stub(ERR_IO_PENDING);
491 
492   base::MockCallback<CompletionOnceCallback> mock_callback;
493   base::MockCallback<base::OnceClosure> checkpoint;
494   std::vector<std::unique_ptr<WebSocketFrame>> frames;
495   {
496     InSequence s;
497     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
498         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
499     EXPECT_CALL(checkpoint, Run());
500     EXPECT_CALL(mock_callback, Run(OK));
501   }
502   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
503               IsError(ERR_IO_PENDING));
504 
505   checkpoint.Run();
506 
507   AppendTo(stub.frames_passed(),
508            WebSocketFrameHeader::kOpCodeText,
509            kFinal | kReserved1,
510            std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
511   stub.callback().Run(OK);
512 
513   ASSERT_EQ(1u, frames.size());
514   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
515   EXPECT_TRUE(frames[0]->header.final);
516   EXPECT_FALSE(frames[0]->header.reserved1);
517   EXPECT_EQ("Hello", ToString(frames[0]));
518 }
519 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending)520 TEST_F(WebSocketDeflateStreamTest,
521        ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) {
522   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
523   const std::string data1("\xf2", 1);
524   const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6);
525   AppendTo(&frames_to_output,
526            WebSocketFrameHeader::kOpCodeText,
527            kReserved1,
528            data1);
529   ReadFramesStub stub1(OK, &frames_to_output), stub2(ERR_IO_PENDING);
530   base::MockCallback<CompletionOnceCallback> mock_callback;
531   base::MockCallback<base::OnceClosure> checkpoint;
532   std::vector<std::unique_ptr<WebSocketFrame>> frames;
533 
534   {
535     InSequence s;
536     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
537         .WillOnce(Invoke(&stub1, &ReadFramesStub::Call))
538         .WillOnce(Invoke(&stub2, &ReadFramesStub::Call));
539     EXPECT_CALL(checkpoint, Run());
540     EXPECT_CALL(mock_callback, Run(OK));
541   }
542   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
543               IsError(ERR_IO_PENDING));
544   ASSERT_EQ(0u, frames.size());
545 
546   AppendTo(stub2.frames_passed(),
547            WebSocketFrameHeader::kOpCodeText,
548            kFinal,
549            data2);
550 
551   checkpoint.Run();
552   stub2.callback().Run(OK);
553 
554   ASSERT_EQ(1u, frames.size());
555   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
556   EXPECT_TRUE(frames[0]->header.final);
557   EXPECT_FALSE(frames[0]->header.reserved1);
558   EXPECT_EQ("Hello", ToString(frames[0]));
559 }
560 
TEST_F(WebSocketDeflateStreamTest,ReadInvalidCompressedPayload)561 TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
562   const std::string data("\xf2\x48\xcdINVALID", 10);
563   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
564   AppendTo(&frames_to_output,
565            WebSocketFrameHeader::kOpCodeText,
566            kFinal | kReserved1,
567            data);
568   ReadFramesStub stub(OK, &frames_to_output);
569   std::vector<std::unique_ptr<WebSocketFrame>> frames;
570 
571   {
572     InSequence s;
573     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
574         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
575   }
576   ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
577             deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()));
578   ASSERT_EQ(0u, frames.size());
579 }
580 
TEST_F(WebSocketDeflateStreamTest,MergeMultipleFramesInReadFrames)581 TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
582   const std::string data1("\xf2\x48\xcd", 3);
583   const std::string data2("\xc9\xc9\x07\x00", 4);
584   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
585   AppendTo(&frames_to_output,
586            WebSocketFrameHeader::kOpCodeText,
587            kReserved1,
588            data1);
589   AppendTo(&frames_to_output,
590            WebSocketFrameHeader::kOpCodeContinuation,
591            kFinal,
592            data2);
593   ReadFramesStub stub(OK, &frames_to_output);
594   std::vector<std::unique_ptr<WebSocketFrame>> frames;
595 
596   {
597     InSequence s;
598     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
599         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
600   }
601   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
602               IsOk());
603   ASSERT_EQ(1u, frames.size());
604   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
605   EXPECT_TRUE(frames[0]->header.final);
606   EXPECT_FALSE(frames[0]->header.reserved1);
607   EXPECT_EQ("Hello", ToString(frames[0]));
608 }
609 
TEST_F(WebSocketDeflateStreamTest,ReadUncompressedEmptyFrames)610 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
611   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
612   AppendTo(&frames_to_output,
613            WebSocketFrameHeader::kOpCodeText,
614            kNoFlag);
615   AppendTo(&frames_to_output,
616            WebSocketFrameHeader::kOpCodeContinuation,
617            kFinal);
618   ReadFramesStub stub(OK, &frames_to_output);
619   std::vector<std::unique_ptr<WebSocketFrame>> frames;
620 
621   {
622     InSequence s;
623     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
624         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
625   }
626   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
627               IsOk());
628   ASSERT_EQ(2u, frames.size());
629   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
630   EXPECT_FALSE(frames[0]->header.final);
631   EXPECT_FALSE(frames[0]->header.reserved1);
632   EXPECT_EQ("", ToString(frames[0]));
633   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
634             frames[1]->header.opcode);
635   EXPECT_TRUE(frames[1]->header.final);
636   EXPECT_FALSE(frames[1]->header.reserved1);
637   EXPECT_EQ("", ToString(frames[1]));
638 }
639 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedEmptyFrames)640 TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
641   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
642   AppendTo(&frames_to_output,
643            WebSocketFrameHeader::kOpCodeText,
644            kReserved1,
645            std::string("\x02\x00", 1));
646   AppendTo(&frames_to_output,
647            WebSocketFrameHeader::kOpCodeContinuation,
648            kFinal);
649   ReadFramesStub stub(OK, &frames_to_output);
650   std::vector<std::unique_ptr<WebSocketFrame>> frames;
651 
652   {
653     InSequence s;
654     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
655         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
656   }
657   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
658               IsOk());
659   ASSERT_EQ(1u, frames.size());
660   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
661   EXPECT_TRUE(frames[0]->header.final);
662   EXPECT_FALSE(frames[0]->header.reserved1);
663   EXPECT_EQ("", ToString(frames[0]));
664 }
665 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedFrameFollowedByEmptyFrame)666 TEST_F(WebSocketDeflateStreamTest,
667        ReadCompressedFrameFollowedByEmptyFrame) {
668   const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
669   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
670   AppendTo(&frames_to_output,
671            WebSocketFrameHeader::kOpCodeText,
672            kReserved1,
673            data);
674   AppendTo(&frames_to_output,
675            WebSocketFrameHeader::kOpCodeContinuation,
676            kFinal);
677   ReadFramesStub stub(OK, &frames_to_output);
678   std::vector<std::unique_ptr<WebSocketFrame>> frames;
679 
680   {
681     InSequence s;
682     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
683         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
684   }
685   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
686               IsOk());
687   ASSERT_EQ(1u, frames.size());
688   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
689   EXPECT_TRUE(frames[0]->header.final);
690   EXPECT_FALSE(frames[0]->header.reserved1);
691   EXPECT_EQ("Hello", ToString(frames[0]));
692 }
693 
TEST_F(WebSocketDeflateStreamTest,ReadControlFrameBetweenDataFrames)694 TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
695   const std::string data1("\xf2\x48\xcd", 3);
696   const std::string data2("\xc9\xc9\x07\x00", 4);
697   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
698   AppendTo(&frames_to_output,
699            WebSocketFrameHeader::kOpCodeText,
700            kReserved1,
701            data1);
702   AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodePing, kFinal);
703   AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2);
704   ReadFramesStub stub(OK, &frames_to_output);
705   std::vector<std::unique_ptr<WebSocketFrame>> frames;
706 
707   {
708     InSequence s;
709     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
710         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
711   }
712   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
713               IsOk());
714   ASSERT_EQ(2u, frames.size());
715   EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames[0]->header.opcode);
716   EXPECT_TRUE(frames[0]->header.final);
717   EXPECT_FALSE(frames[0]->header.reserved1);
718   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
719   EXPECT_TRUE(frames[1]->header.final);
720   EXPECT_FALSE(frames[1]->header.reserved1);
721   EXPECT_EQ("Hello", ToString(frames[1]));
722 }
723 
TEST_F(WebSocketDeflateStreamTest,SplitToMultipleFramesInReadFrames)724 TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) {
725   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
726   deflater.Initialize(kWindowBits);
727   const size_t kSize = kChunkSize * 3;
728   const std::string original_data(kSize, 'a');
729   deflater.AddBytes(original_data.data(), original_data.size());
730   deflater.Finish();
731 
732   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
733   AppendTo(&frames_to_output,
734            WebSocketFrameHeader::kOpCodeBinary,
735            kFinal | kReserved1,
736            ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
737 
738   ReadFramesStub stub(OK, &frames_to_output);
739   std::vector<std::unique_ptr<WebSocketFrame>> frames;
740   {
741     InSequence s;
742     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
743         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
744   }
745 
746   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
747               IsOk());
748   ASSERT_EQ(3u, frames.size());
749   EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
750   EXPECT_FALSE(frames[0]->header.final);
751   EXPECT_FALSE(frames[0]->header.reserved1);
752   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
753   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
754             frames[1]->header.opcode);
755   EXPECT_FALSE(frames[1]->header.final);
756   EXPECT_FALSE(frames[1]->header.reserved1);
757   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[1]->header.payload_length));
758   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
759             frames[2]->header.opcode);
760   EXPECT_TRUE(frames[2]->header.final);
761   EXPECT_FALSE(frames[2]->header.reserved1);
762   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[2]->header.payload_length));
763   EXPECT_EQ(original_data,
764             ToString(frames[0]) + ToString(frames[1]) + ToString(frames[2]));
765 }
766 
TEST_F(WebSocketDeflateStreamTest,InflaterInternalDataCanBeEmpty)767 TEST_F(WebSocketDeflateStreamTest, InflaterInternalDataCanBeEmpty) {
768   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
769   deflater.Initialize(kWindowBits);
770   const std::string original_data(kChunkSize, 'a');
771   deflater.AddBytes(original_data.data(), original_data.size());
772   deflater.Finish();
773 
774   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
775   AppendTo(&frames_to_output,
776            WebSocketFrameHeader::kOpCodeBinary,
777            kReserved1,
778            ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
779   AppendTo(&frames_to_output,
780            WebSocketFrameHeader::kOpCodeBinary,
781            kFinal,
782            "");
783 
784   ReadFramesStub stub(OK, &frames_to_output);
785   std::vector<std::unique_ptr<WebSocketFrame>> frames;
786   {
787     InSequence s;
788     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
789         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
790   }
791 
792   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
793               IsOk());
794   ASSERT_EQ(2u, frames.size());
795   EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
796   EXPECT_FALSE(frames[0]->header.final);
797   EXPECT_FALSE(frames[0]->header.reserved1);
798   EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
799 
800   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
801             frames[1]->header.opcode);
802   EXPECT_TRUE(frames[1]->header.final);
803   EXPECT_FALSE(frames[1]->header.reserved1);
804   EXPECT_EQ(0u, static_cast<size_t>(frames[1]->header.payload_length));
805   EXPECT_EQ(original_data, ToString(frames[0]) + ToString(frames[1]));
806 }
807 
TEST_F(WebSocketDeflateStreamTest,Reserved1TurnsOnDuringReadingCompressedContinuationFrame)808 TEST_F(WebSocketDeflateStreamTest,
809        Reserved1TurnsOnDuringReadingCompressedContinuationFrame) {
810   const std::string data1("\xf2\x48\xcd", 3);
811   const std::string data2("\xc9\xc9\x07\x00", 4);
812   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
813   AppendTo(&frames_to_output,
814            WebSocketFrameHeader::kOpCodeText,
815            kReserved1,
816            data1);
817   AppendTo(&frames_to_output,
818            WebSocketFrameHeader::kOpCodeContinuation,
819            kFinal | kReserved1,
820            data2);
821   ReadFramesStub stub(OK, &frames_to_output);
822   std::vector<std::unique_ptr<WebSocketFrame>> frames;
823 
824   {
825     InSequence s;
826     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
827         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
828   }
829   ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
830             deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()));
831 }
832 
TEST_F(WebSocketDeflateStreamTest,Reserved1TurnsOnDuringReadingUncompressedContinuationFrame)833 TEST_F(WebSocketDeflateStreamTest,
834        Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) {
835   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
836   AppendTo(&frames_to_output,
837            WebSocketFrameHeader::kOpCodeText,
838            kNoFlag,
839            "hello");
840   AppendTo(&frames_to_output,
841            WebSocketFrameHeader::kOpCodeContinuation,
842            kFinal | kReserved1,
843            "world");
844   ReadFramesStub stub(OK, &frames_to_output);
845   std::vector<std::unique_ptr<WebSocketFrame>> frames;
846 
847   {
848     InSequence s;
849     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
850         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
851   }
852   ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
853             deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()));
854 }
855 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedMessages)856 TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
857   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
858   AppendTo(&frames_to_output,
859            WebSocketFrameHeader::kOpCodeText,
860            kFinal | kReserved1,
861            std::string(
862                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x31\x04\x00", 13));
863   AppendTo(&frames_to_output,
864            WebSocketFrameHeader::kOpCodeText,
865            kFinal | kReserved1,
866            std::string("\x4a\x86\x33\x8d\x00\x00", 6));
867   ReadFramesStub stub(OK, &frames_to_output);
868   std::vector<std::unique_ptr<WebSocketFrame>> frames;
869 
870   {
871     InSequence s;
872     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
873         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
874   }
875   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
876               IsOk());
877   ASSERT_EQ(2u, frames.size());
878   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
879   EXPECT_TRUE(frames[0]->header.final);
880   EXPECT_FALSE(frames[0]->header.reserved1);
881   EXPECT_EQ("compressed1", ToString(frames[0]));
882   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
883   EXPECT_TRUE(frames[1]->header.final);
884   EXPECT_FALSE(frames[1]->header.reserved1);
885   EXPECT_EQ("compressed2", ToString(frames[1]));
886 }
887 
TEST_F(WebSocketDeflateStreamTest,ReadUncompressedMessages)888 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
889   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
890   AppendTo(&frames_to_output,
891            WebSocketFrameHeader::kOpCodeText,
892            kFinal,
893            "uncompressed1");
894   AppendTo(&frames_to_output,
895            WebSocketFrameHeader::kOpCodeText,
896            kFinal,
897            "uncompressed2");
898   ReadFramesStub stub(OK, &frames_to_output);
899   std::vector<std::unique_ptr<WebSocketFrame>> frames;
900 
901   {
902     InSequence s;
903     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
904         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
905   }
906   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
907               IsOk());
908   ASSERT_EQ(2u, frames.size());
909   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
910   EXPECT_TRUE(frames[0]->header.final);
911   EXPECT_FALSE(frames[0]->header.reserved1);
912   EXPECT_EQ("uncompressed1", ToString(frames[0]));
913   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
914   EXPECT_TRUE(frames[1]->header.final);
915   EXPECT_FALSE(frames[1]->header.reserved1);
916   EXPECT_EQ("uncompressed2", ToString(frames[1]));
917 }
918 
TEST_F(WebSocketDeflateStreamTest,ReadCompressedMessageThenUncompressedMessage)919 TEST_F(WebSocketDeflateStreamTest,
920        ReadCompressedMessageThenUncompressedMessage) {
921   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
922   AppendTo(&frames_to_output,
923            WebSocketFrameHeader::kOpCodeText,
924            kFinal | kReserved1,
925            std::string(
926                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
927   AppendTo(&frames_to_output,
928            WebSocketFrameHeader::kOpCodeText,
929            kFinal,
930            "uncompressed");
931   ReadFramesStub stub(OK, &frames_to_output);
932   std::vector<std::unique_ptr<WebSocketFrame>> frames;
933 
934   {
935     InSequence s;
936     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
937         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
938   }
939   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
940               IsOk());
941   ASSERT_EQ(2u, frames.size());
942   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
943   EXPECT_TRUE(frames[0]->header.final);
944   EXPECT_FALSE(frames[0]->header.reserved1);
945   EXPECT_EQ("compressed", ToString(frames[0]));
946   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
947   EXPECT_TRUE(frames[1]->header.final);
948   EXPECT_FALSE(frames[1]->header.reserved1);
949   EXPECT_EQ("uncompressed", ToString(frames[1]));
950 }
951 
TEST_F(WebSocketDeflateStreamTest,ReadUncompressedMessageThenCompressedMessage)952 TEST_F(WebSocketDeflateStreamTest,
953        ReadUncompressedMessageThenCompressedMessage) {
954   std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
955   AppendTo(&frames_to_output,
956            WebSocketFrameHeader::kOpCodeText,
957            kFinal,
958            "uncompressed");
959   AppendTo(&frames_to_output,
960            WebSocketFrameHeader::kOpCodeText,
961            kFinal | kReserved1,
962            std::string(
963                "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
964   ReadFramesStub stub(OK, &frames_to_output);
965   std::vector<std::unique_ptr<WebSocketFrame>> frames;
966 
967   {
968     InSequence s;
969     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
970         .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
971   }
972   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
973               IsOk());
974   ASSERT_EQ(2u, frames.size());
975   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
976   EXPECT_TRUE(frames[0]->header.final);
977   EXPECT_FALSE(frames[0]->header.reserved1);
978   EXPECT_EQ("uncompressed", ToString(frames[0]));
979   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
980   EXPECT_TRUE(frames[1]->header.final);
981   EXPECT_FALSE(frames[1]->header.reserved1);
982   EXPECT_EQ("compressed", ToString(frames[1]));
983 }
984 
985 // This is a regression test for crbug.com/343506.
TEST_F(WebSocketDeflateStreamTest,ReadEmptyAsyncFrame)986 TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) {
987   std::vector<std::unique_ptr<ReadFramesStub>> stub_vector;
988   stub_vector.push_back(std::make_unique<ReadFramesStub>(ERR_IO_PENDING));
989   stub_vector.push_back(std::make_unique<ReadFramesStub>(ERR_IO_PENDING));
990   base::MockCallback<CompletionOnceCallback> mock_callback;
991   std::vector<std::unique_ptr<WebSocketFrame>> frames;
992 
993   {
994     InSequence s;
995     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
996         .WillOnce(Invoke(stub_vector[0].get(), &ReadFramesStub::Call));
997 
998     EXPECT_CALL(*mock_stream_, ReadFramesInternal(&frames, _))
999         .WillOnce(Invoke(stub_vector[1].get(), &ReadFramesStub::Call));
1000 
1001     EXPECT_CALL(mock_callback, Run(OK));
1002   }
1003 
1004   ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
1005               IsError(ERR_IO_PENDING));
1006   AppendTo(stub_vector[0]->frames_passed(),
1007            WebSocketFrameHeader::kOpCodeText,
1008            kReserved1,
1009            std::string());
1010   stub_vector[0]->callback().Run(OK);
1011   AppendTo(stub_vector[1]->frames_passed(),
1012            WebSocketFrameHeader::kOpCodeContinuation,
1013            kFinal,
1014            std::string("\x02\x00"));
1015   stub_vector[1]->callback().Run(OK);
1016   ASSERT_EQ(1u, frames.size());
1017   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
1018   EXPECT_EQ("", ToString(frames[0]));
1019 }
1020 
TEST_F(WebSocketDeflateStreamTest,WriteEmpty)1021 TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
1022   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1023   {
1024     InSequence s;
1025     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _)).Times(0);
1026   }
1027   EXPECT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1028               IsOk());
1029 }
1030 
TEST_F(WebSocketDeflateStreamTest,WriteFailedImmediately)1031 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
1032   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1033   {
1034     InSequence s;
1035     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1036         .WillOnce(Return(ERR_FAILED));
1037   }
1038 
1039   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello");
1040   predictor_->AddFramesToBeInput(frames);
1041   EXPECT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1042               IsError(ERR_FAILED));
1043   predictor_->Clear();
1044 }
1045 
TEST_F(WebSocketDeflateStreamTest,WriteFrameImmediately)1046 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
1047   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1048   WriteFramesStub stub(predictor_, OK);
1049   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1050   predictor_->AddFramesToBeInput(frames);
1051   {
1052     InSequence s;
1053     EXPECT_CALL(*mock_stream_, WriteFramesInternal(_, _))
1054         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1055   }
1056   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1057               IsOk());
1058   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1059       *stub.frames();
1060   ASSERT_EQ(1u, frames_passed.size());
1061   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1062   EXPECT_TRUE(frames_passed[0]->header.final);
1063   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1064   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1065             ToString(frames_passed[0]));
1066 }
1067 
TEST_F(WebSocketDeflateStreamTest,WriteFrameAsync)1068 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
1069   WriteFramesStub stub(predictor_, ERR_IO_PENDING);
1070   base::MockCallback<CompletionOnceCallback> mock_callback;
1071   base::MockCallback<base::OnceClosure> checkpoint;
1072   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1073   {
1074     InSequence s;
1075     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1076         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1077     EXPECT_CALL(checkpoint, Run());
1078     EXPECT_CALL(mock_callback, Run(OK));
1079   }
1080   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1081   predictor_->AddFramesToBeInput(frames);
1082   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, mock_callback.Get()),
1083               IsError(ERR_IO_PENDING));
1084 
1085   checkpoint.Run();
1086   stub.callback().Run(OK);
1087 
1088   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1089       *stub.frames();
1090   ASSERT_EQ(1u, frames_passed.size());
1091   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1092   EXPECT_TRUE(frames_passed[0]->header.final);
1093   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1094   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1095             ToString(frames_passed[0]));
1096 }
1097 
TEST_F(WebSocketDeflateStreamTest,WriteControlFrameBetweenDataFrames)1098 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
1099   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1100   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
1101   AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
1102   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
1103   predictor_->AddFramesToBeInput(frames);
1104   WriteFramesStub stub(predictor_, OK);
1105 
1106   {
1107     InSequence s;
1108     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1109         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1110   }
1111   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1112               IsOk());
1113   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1114       *stub.frames();
1115   ASSERT_EQ(2u, frames_passed.size());
1116   EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
1117   EXPECT_TRUE(frames_passed[0]->header.final);
1118   EXPECT_FALSE(frames_passed[0]->header.reserved1);
1119   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1120   EXPECT_TRUE(frames_passed[1]->header.final);
1121   EXPECT_TRUE(frames_passed[1]->header.reserved1);
1122   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1123             ToString(frames_passed[1]));
1124 }
1125 
TEST_F(WebSocketDeflateStreamTest,WriteEmptyMessage)1126 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
1127   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1128   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
1129   predictor_->AddFramesToBeInput(frames);
1130   WriteFramesStub stub(predictor_, OK);
1131 
1132   {
1133     InSequence s;
1134     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1135         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1136   }
1137   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1138               IsOk());
1139   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1140       *stub.frames();
1141   ASSERT_EQ(1u, frames_passed.size());
1142   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1143   EXPECT_TRUE(frames_passed[0]->header.final);
1144   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1145   EXPECT_EQ(std::string("\x00", 1), ToString(frames_passed[0]));
1146 }
1147 
TEST_F(WebSocketDeflateStreamTest,WriteUncompressedMessage)1148 TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
1149   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1150   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
1151   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
1152   predictor_->AddFramesToBeInput(frames);
1153   WriteFramesStub stub(predictor_, OK);
1154 
1155   predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE);
1156 
1157   {
1158     InSequence s;
1159     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1160         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1161   }
1162   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1163               IsOk());
1164   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1165       *stub.frames();
1166   ASSERT_EQ(2u, frames_passed.size());
1167   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1168   EXPECT_FALSE(frames_passed[0]->header.final);
1169   EXPECT_FALSE(frames_passed[0]->header.reserved1);
1170   EXPECT_EQ("AAAA", ToString(frames_passed[0]));
1171   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1172             frames_passed[1]->header.opcode);
1173   EXPECT_TRUE(frames_passed[1]->header.final);
1174   EXPECT_FALSE(frames_passed[1]->header.reserved1);
1175   EXPECT_EQ("AAA", ToString(frames_passed[1]));
1176 }
1177 
TEST_F(WebSocketDeflateStreamTest,LargeDeflatedFramesShouldBeSplit)1178 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
1179   WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
1180   LinearCongruentialGenerator lcg(133);
1181   WriteFramesStub stub(predictor_, OK);
1182   const size_t size = 1024;
1183 
1184   {
1185     InSequence s;
1186     EXPECT_CALL(*mock_stream_, WriteFramesInternal(_, _))
1187         .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
1188   }
1189   std::vector<std::unique_ptr<WebSocketFrame>> total_compressed_frames;
1190   std::vector<std::string> buffers;
1191 
1192   deflater.Initialize(kWindowBits);
1193   while (true) {
1194     bool is_final = (total_compressed_frames.size() >= 2);
1195     std::vector<std::unique_ptr<WebSocketFrame>> frames;
1196     std::string data;
1197     for (size_t i = 0; i < size; ++i)
1198       data += static_cast<char>(lcg.Generate());
1199     deflater.AddBytes(data.data(), data.size());
1200     FrameFlag flag = is_final ? kFinal : kNoFlag;
1201     AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
1202     predictor_->AddFramesToBeInput(frames);
1203     ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1204                 IsOk());
1205     for (auto& frame : *stub.frames()) {
1206       buffers.push_back(
1207           std::string(frame->payload, frame->header.payload_length));
1208       frame->payload = (buffers.end() - 1)->data();
1209     }
1210     total_compressed_frames.insert(
1211         total_compressed_frames.end(),
1212         std::make_move_iterator(stub.frames()->begin()),
1213         std::make_move_iterator(stub.frames()->end()));
1214     stub.frames()->clear();
1215     if (is_final)
1216       break;
1217   }
1218   deflater.Finish();
1219   std::string total_deflated;
1220   for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
1221     WebSocketFrame* frame = total_compressed_frames[i].get();
1222     const WebSocketFrameHeader& header = frame->header;
1223     if (i > 0) {
1224       EXPECT_EQ(header.kOpCodeContinuation, header.opcode);
1225       EXPECT_FALSE(header.reserved1);
1226     } else {
1227       EXPECT_EQ(header.kOpCodeBinary, header.opcode);
1228       EXPECT_TRUE(header.reserved1);
1229     }
1230     const bool is_final_frame = (i + 1 == total_compressed_frames.size());
1231     EXPECT_EQ(is_final_frame, header.final);
1232     if (!is_final_frame)
1233       EXPECT_GT(header.payload_length, 0ul);
1234     total_deflated += ToString(frame);
1235   }
1236   EXPECT_EQ(total_deflated,
1237             ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
1238 }
1239 
TEST_F(WebSocketDeflateStreamTest,WriteMultipleMessages)1240 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
1241   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1242   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1243   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1244   predictor_->AddFramesToBeInput(frames);
1245   WriteFramesStub stub(predictor_, OK);
1246 
1247   {
1248     InSequence s;
1249     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1250         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1251   }
1252   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1253               IsOk());
1254   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1255       *stub.frames();
1256   ASSERT_EQ(2u, frames_passed.size());
1257   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1258   EXPECT_TRUE(frames_passed[0]->header.final);
1259   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1260   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1261             ToString(frames_passed[0]));
1262   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1263   EXPECT_TRUE(frames_passed[1]->header.final);
1264   EXPECT_TRUE(frames_passed[1]->header.reserved1);
1265   EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1]));
1266 }
1267 
TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,WriteMultipleMessages)1268 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1269        WriteMultipleMessages) {
1270   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1271   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1272   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1273   predictor_->AddFramesToBeInput(frames);
1274   WriteFramesStub stub(predictor_, OK);
1275 
1276   {
1277     InSequence s;
1278     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1279         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1280   }
1281   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1282               IsOk());
1283   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1284       *stub.frames();
1285   ASSERT_EQ(2u, frames_passed.size());
1286   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1287   EXPECT_TRUE(frames_passed[0]->header.final);
1288   EXPECT_TRUE(frames_passed[0]->header.reserved1);
1289   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1290             ToString(frames_passed[0]));
1291   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1292   EXPECT_TRUE(frames_passed[1]->header.final);
1293   EXPECT_TRUE(frames_passed[1]->header.reserved1);
1294   EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1295             ToString(frames_passed[1]));
1296 }
1297 
1298 // In order to check the stream works correctly for multiple
1299 // "PossiblyCompressedMessage"s, we test various messages at one test case.
TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,WritePossiblyCompressMessages)1300 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1301        WritePossiblyCompressMessages) {
1302   std::vector<std::unique_ptr<WebSocketFrame>> frames;
1303   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
1304   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
1305   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
1306   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA");
1307   AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX");
1308   AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY");
1309   predictor_->AddFramesToBeInput(frames);
1310   WriteFramesStub stub(predictor_, OK);
1311   predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE);
1312 
1313   {
1314     InSequence s;
1315     EXPECT_CALL(*mock_stream_, WriteFramesInternal(&frames, _))
1316         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1317   }
1318   ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1319               IsOk());
1320   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1321       *stub.frames();
1322   ASSERT_EQ(5u, frames_passed.size());
1323 
1324   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1325   EXPECT_FALSE(frames_passed[0]->header.final);
1326   EXPECT_FALSE(frames_passed[0]->header.reserved1);
1327   EXPECT_EQ("He", ToString(frames_passed[0]));
1328   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1329             frames_passed[1]->header.opcode);
1330   EXPECT_TRUE(frames_passed[1]->header.final);
1331   EXPECT_FALSE(frames_passed[1]->header.reserved1);
1332   EXPECT_EQ("llo", ToString(frames_passed[1]));
1333 
1334   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode);
1335   EXPECT_TRUE(frames_passed[2]->header.final);
1336   EXPECT_TRUE(frames_passed[2]->header.reserved1);
1337   EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6),
1338             ToString(frames_passed[2]));
1339 
1340   EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode);
1341   EXPECT_FALSE(frames_passed[3]->header.final);
1342   EXPECT_FALSE(frames_passed[3]->header.reserved1);
1343   EXPECT_EQ("XX", ToString(frames_passed[3]));
1344   EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1345             frames_passed[4]->header.opcode);
1346   EXPECT_TRUE(frames_passed[4]->header.final);
1347   EXPECT_FALSE(frames_passed[4]->header.reserved1);
1348   EXPECT_EQ("YY", ToString(frames_passed[4]));
1349 }
1350 
1351 // This is based on the similar test from websocket_deflater_test.cc
TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest,WindowBits8)1352 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits8) {
1353   SetUpWithWindowBits(8);
1354   AddCompressibleFrameString();
1355   WriteFramesStub stub(predictor_, OK);
1356   {
1357     InSequence s;
1358     EXPECT_CALL(*mock_stream_, WriteFramesInternal(_, _))
1359         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1360   }
1361   ASSERT_THAT(deflate_stream_->WriteFrames(&frames_, CompletionOnceCallback()),
1362               IsOk());
1363   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1364       *stub.frames();
1365   ASSERT_EQ(1u, frames_passed.size());
1366   EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
1367                         "(?7\xb3\x34\x17\x00", 21),
1368             ToString(frames_passed[0]));
1369 }
1370 
1371 // The same input with window_bits=10 returns smaller output.
TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest,WindowBits10)1372 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits10) {
1373   SetUpWithWindowBits(10);
1374   AddCompressibleFrameString();
1375   WriteFramesStub stub(predictor_, OK);
1376   {
1377     InSequence s;
1378     EXPECT_CALL(*mock_stream_, WriteFramesInternal(_, _))
1379         .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1380   }
1381   ASSERT_THAT(deflate_stream_->WriteFrames(&frames_, CompletionOnceCallback()),
1382               IsOk());
1383   const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1384       *stub.frames();
1385   ASSERT_EQ(1u, frames_passed.size());
1386   EXPECT_EQ(
1387       std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
1388       ToString(frames_passed[0]));
1389 }
1390 
1391 }  // namespace
1392 
1393 }  // namespace net
1394