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