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