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.
5 #include "net/websockets/websocket_deflate_stream.h"
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"
31 typedef ::testing::MockFunction<void(int)> MockCallback; // NOLINT
33 using ::testing::InSequence;
34 using ::testing::Invoke;
35 using ::testing::Return;
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.
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;
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());
54 std::string ToString(IOBufferWithSize* buffer) {
55 return std::string(buffer->data(), buffer->size());
58 std::string ToString(const scoped_refptr<IOBufferWithSize>& buffer) {
59 return ToString(buffer.get());
62 std::string ToString(IOBuffer* buffer, size_t size) {
63 return std::string(buffer->data(), size);
66 std::string ToString(const scoped_refptr<IOBuffer>& buffer, size_t size) {
67 return ToString(buffer.get(), size);
70 std::string ToString(const WebSocketFrame* frame) {
71 return frame->data ? ToString(frame->data, frame->header.payload_length) : "";
74 void AppendTo(ScopedVector<WebSocketFrame>* frames,
75 WebSocketFrameHeader::OpCode opcode,
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());
86 void AppendTo(ScopedVector<WebSocketFrame>* frames,
87 WebSocketFrameHeader::OpCode opcode,
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());
95 class MockWebSocketStream : public WebSocketStream {
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());
106 // This mock class relies on some assumptions.
107 // - RecordInputDataFrame is called after the corresponding WriteFrames
109 // - RecordWrittenDataFrame is called before writing the frame.
110 class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor {
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.";
119 if (!frames_written_.empty()) {
120 ADD_FAILURE() << "There are extra written frames.";
125 // WebSocketDeflatePredictor functions.
126 virtual Result Predict(const ScopedVector<WebSocketFrame>& frames,
127 size_t frame_index) OVERRIDE {
130 virtual void RecordInputDataFrame(const WebSocketFrame* frame) OVERRIDE {
131 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
132 ADD_FAILURE() << "Control frames should not be recorded.";
135 if (frame->header.reserved1) {
136 ADD_FAILURE() << "Input frame may not be compressed.";
139 if (frames_to_be_input_.empty()) {
140 ADD_FAILURE() << "Unexpected input data frame";
143 if (frame != frames_to_be_input_.front()) {
144 ADD_FAILURE() << "Input data frame does not match the expectation.";
147 frames_to_be_input_.pop_front();
149 virtual void RecordWrittenDataFrame(const WebSocketFrame* frame) OVERRIDE {
150 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
151 ADD_FAILURE() << "Control frames should not be recorded.";
154 frames_written_.push_back(frame);
157 // Sets |result_| for the |Predict| return value.
158 void set_result(Result result) { result_ = result; }
160 // Adds |frame| as an expectation of future |RecordInputDataFrame| call.
161 void AddFrameToBeInput(const WebSocketFrame* frame) {
162 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
164 frames_to_be_input_.push_back(frame);
166 // Verifies that |frame| is recorded in order.
167 void VerifySentFrame(const WebSocketFrame* frame) {
168 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
170 if (frames_written_.empty()) {
171 ADD_FAILURE() << "There are missing frames to be written.";
174 if (frame != frames_written_.front()) {
175 ADD_FAILURE() << "Written data frame does not match the expectation.";
178 frames_written_.pop_front();
180 void AddFramesToBeInput(const ScopedVector<WebSocketFrame>& frames) {
181 for (size_t i = 0; i < frames.size(); ++i)
182 AddFrameToBeInput(frames[i]);
184 void VerifySentFrames(const ScopedVector<WebSocketFrame>& frames) {
185 for (size_t i = 0; i < frames.size(); ++i)
186 VerifySentFrame(frames[i]);
188 // Call this method in order to disable checks in the destructor when
189 // WriteFrames fails.
191 frames_to_be_input_.clear();
192 frames_written_.clear();
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_;
206 DISALLOW_COPY_AND_ASSIGN(WebSocketDeflatePredictorMock);
209 class WebSocketDeflateStreamTest : public ::testing::Test {
211 WebSocketDeflateStreamTest()
212 : mock_stream_(NULL),
214 virtual ~WebSocketDeflateStreamTest() {}
216 virtual void SetUp() {
217 Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, kWindowBits);
221 // Initialize deflate_stream_ with the given parameters.
222 void Initialize(WebSocketDeflater::ContextTakeOverMode mode,
224 mock_stream_ = new testing::StrictMock<MockWebSocketStream>;
225 predictor_ = new WebSocketDeflatePredictorMock;
226 deflate_stream_.reset(new WebSocketDeflateStream(
227 scoped_ptr<WebSocketStream>(mock_stream_),
230 scoped_ptr<WebSocketDeflatePredictor>(predictor_)));
233 scoped_ptr<WebSocketDeflateStream> deflate_stream_;
234 // Owned by |deflate_stream_|.
235 MockWebSocketStream* mock_stream_;
236 // Owned by |deflate_stream_|.
237 WebSocketDeflatePredictorMock* predictor_;
240 // Since WebSocketDeflater with DoNotTakeOverContext is well tested at
241 // websocket_deflater_test.cc, we have only a few tests for this configuration
243 class WebSocketDeflateStreamWithDoNotTakeOverContextTest
244 : public WebSocketDeflateStreamTest {
246 WebSocketDeflateStreamWithDoNotTakeOverContextTest() {}
247 virtual ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() {}
249 virtual void SetUp() {
250 Initialize(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT, kWindowBits);
254 class WebSocketDeflateStreamWithClientWindowBitsTest
255 : public WebSocketDeflateStreamTest {
257 WebSocketDeflateStreamWithClientWindowBitsTest() {}
258 virtual ~WebSocketDeflateStreamWithClientWindowBitsTest() {}
260 // Overridden to postpone the call to Initialize().
261 virtual void SetUp() {}
263 // This needs to be called explicitly from the tests.
264 void SetUpWithWindowBits(int window_bits) {
265 Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, window_bits);
268 // Add a frame which will be compressed to a smaller size if the window
269 // size is large enough.
270 void AddCompressibleFrameString() {
271 const std::string word = "Chromium";
272 const std::string payload = word + std::string(256, 'a') + word;
273 AppendTo(&frames_, WebSocketFrameHeader::kOpCodeText, kFinal, payload);
274 predictor_->AddFramesToBeInput(frames_);
278 ScopedVector<WebSocketFrame> frames_;
281 // ReadFrameStub is a stub for WebSocketStream::ReadFrames.
282 // It returns |result_| and |frames_to_output_| to the caller and
283 // saves parameters to |frames_passed_| and |callback_|.
284 class ReadFramesStub {
286 explicit ReadFramesStub(int result) : result_(result) {}
288 ReadFramesStub(int result, ScopedVector<WebSocketFrame>* frames_to_output)
290 frames_to_output_.swap(*frames_to_output);
293 int Call(ScopedVector<WebSocketFrame>* frames,
294 const CompletionCallback& callback) {
295 DCHECK(frames->empty());
296 frames_passed_ = frames;
297 callback_ = callback;
298 frames->swap(frames_to_output_);
302 int result() const { return result_; }
303 const CompletionCallback callback() const { return callback_; }
304 ScopedVector<WebSocketFrame>* frames_passed() {
305 return frames_passed_;
310 CompletionCallback callback_;
311 ScopedVector<WebSocketFrame> frames_to_output_;
312 ScopedVector<WebSocketFrame>* frames_passed_;
315 // WriteFramesStub is a stub for WebSocketStream::WriteFrames.
316 // It returns |result_| and |frames_| to the caller and
317 // saves |callback| parameter to |callback_|.
318 class WriteFramesStub {
320 explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor,
322 : result_(result), predictor_(predictor) {}
324 int Call(ScopedVector<WebSocketFrame>* frames,
325 const CompletionCallback& callback) {
326 frames_.insert(frames_.end(), frames->begin(), frames->end());
327 frames->weak_clear();
328 callback_ = callback;
329 predictor_->VerifySentFrames(frames_);
333 int result() const { return result_; }
334 const CompletionCallback callback() const { return callback_; }
335 ScopedVector<WebSocketFrame>* frames() { return &frames_; }
339 CompletionCallback callback_;
340 ScopedVector<WebSocketFrame> frames_;
341 WebSocketDeflatePredictorMock* predictor_;
344 TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
345 ScopedVector<WebSocketFrame> frames;
346 CompletionCallback callback;
349 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
350 .WillOnce(Return(ERR_FAILED));
352 EXPECT_EQ(ERR_FAILED, deflate_stream_->ReadFrames(&frames, callback));
355 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
356 ScopedVector<WebSocketFrame> frames_to_output;
357 AppendTo(&frames_to_output,
358 WebSocketFrameHeader::kOpCodeText,
361 ReadFramesStub stub(OK, &frames_to_output);
362 ScopedVector<WebSocketFrame> frames;
366 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
367 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
369 CompletionCallback callback;
370 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
371 ASSERT_EQ(1u, frames.size());
372 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
373 EXPECT_TRUE(frames[0]->header.final);
374 EXPECT_FALSE(frames[0]->header.reserved1);
375 EXPECT_EQ("hello", ToString(frames[0]));
378 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
379 ReadFramesStub stub(ERR_IO_PENDING);
380 ScopedVector<WebSocketFrame> frames;
381 MockCallback mock_callback, checkpoint;
382 CompletionCallback callback =
383 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
387 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
388 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
389 EXPECT_CALL(checkpoint, Call(0));
390 EXPECT_CALL(mock_callback, Call(OK));
392 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
393 ASSERT_EQ(0u, frames.size());
397 AppendTo(stub.frames_passed(),
398 WebSocketFrameHeader::kOpCodeText,
401 stub.callback().Run(OK);
402 ASSERT_EQ(1u, frames.size());
403 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
404 EXPECT_TRUE(frames[0]->header.final);
405 EXPECT_FALSE(frames[0]->header.reserved1);
406 EXPECT_EQ("hello", ToString(frames[0]));
409 TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
410 ReadFramesStub stub(ERR_IO_PENDING);
411 ScopedVector<WebSocketFrame> frames;
412 MockCallback mock_callback, checkpoint;
413 CompletionCallback callback =
414 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
418 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
419 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
420 EXPECT_CALL(checkpoint, Call(0));
421 EXPECT_CALL(mock_callback, Call(ERR_FAILED));
423 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
424 ASSERT_EQ(0u, frames.size());
428 AppendTo(stub.frames_passed(),
429 WebSocketFrameHeader::kOpCodeText,
432 stub.callback().Run(ERR_FAILED);
433 ASSERT_EQ(0u, frames.size());
436 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) {
437 ScopedVector<WebSocketFrame> frames_to_output;
438 AppendTo(&frames_to_output,
439 WebSocketFrameHeader::kOpCodeText,
441 std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
442 ReadFramesStub stub(OK, &frames_to_output);
443 CompletionCallback callback;
444 ScopedVector<WebSocketFrame> frames;
447 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
448 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
450 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
451 ASSERT_EQ(1u, frames.size());
452 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
453 EXPECT_TRUE(frames[0]->header.final);
454 EXPECT_FALSE(frames[0]->header.reserved1);
455 EXPECT_EQ("Hello", ToString(frames[0]));
458 TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) {
459 ReadFramesStub stub(ERR_IO_PENDING);
460 MockCallback mock_callback, checkpoint;
461 CompletionCallback callback =
462 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
463 ScopedVector<WebSocketFrame> frames;
466 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
467 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
468 EXPECT_CALL(checkpoint, Call(0));
469 EXPECT_CALL(mock_callback, Call(OK));
471 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
475 AppendTo(stub.frames_passed(),
476 WebSocketFrameHeader::kOpCodeText,
478 std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
479 stub.callback().Run(OK);
481 ASSERT_EQ(1u, frames.size());
482 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
483 EXPECT_TRUE(frames[0]->header.final);
484 EXPECT_FALSE(frames[0]->header.reserved1);
485 EXPECT_EQ("Hello", ToString(frames[0]));
488 TEST_F(WebSocketDeflateStreamTest,
489 ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) {
490 ScopedVector<WebSocketFrame> frames_to_output;
491 const std::string data1("\xf2", 1);
492 const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6);
493 AppendTo(&frames_to_output,
494 WebSocketFrameHeader::kOpCodeText,
497 ReadFramesStub stub1(OK, &frames_to_output), stub2(ERR_IO_PENDING);
498 MockCallback mock_callback, checkpoint;
499 CompletionCallback callback =
500 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
501 ScopedVector<WebSocketFrame> frames;
505 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
506 .WillOnce(Invoke(&stub1, &ReadFramesStub::Call))
507 .WillOnce(Invoke(&stub2, &ReadFramesStub::Call));
508 EXPECT_CALL(checkpoint, Call(0));
509 EXPECT_CALL(mock_callback, Call(OK));
511 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->ReadFrames(&frames, callback));
512 ASSERT_EQ(0u, frames.size());
514 AppendTo(stub2.frames_passed(),
515 WebSocketFrameHeader::kOpCodeText,
520 stub2.callback().Run(OK);
522 ASSERT_EQ(1u, frames.size());
523 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
524 EXPECT_TRUE(frames[0]->header.final);
525 EXPECT_FALSE(frames[0]->header.reserved1);
526 EXPECT_EQ("Hello", ToString(frames[0]));
529 TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
530 const std::string data("\xf2\x48\xcdINVALID", 10);
531 ScopedVector<WebSocketFrame> frames_to_output;
532 AppendTo(&frames_to_output,
533 WebSocketFrameHeader::kOpCodeText,
536 ReadFramesStub stub(OK, &frames_to_output);
537 CompletionCallback callback;
538 ScopedVector<WebSocketFrame> frames;
542 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
543 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
545 ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
546 deflate_stream_->ReadFrames(&frames, callback));
547 ASSERT_EQ(0u, frames.size());
550 TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
551 const std::string data1("\xf2\x48\xcd", 3);
552 const std::string data2("\xc9\xc9\x07\x00", 4);
553 ScopedVector<WebSocketFrame> frames_to_output;
554 AppendTo(&frames_to_output,
555 WebSocketFrameHeader::kOpCodeText,
558 AppendTo(&frames_to_output,
559 WebSocketFrameHeader::kOpCodeContinuation,
562 ReadFramesStub stub(OK, &frames_to_output);
563 CompletionCallback callback;
564 ScopedVector<WebSocketFrame> frames;
568 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
569 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
571 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
572 ASSERT_EQ(1u, frames.size());
573 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
574 EXPECT_TRUE(frames[0]->header.final);
575 EXPECT_FALSE(frames[0]->header.reserved1);
576 EXPECT_EQ("Hello", ToString(frames[0]));
579 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
580 ScopedVector<WebSocketFrame> frames_to_output;
581 AppendTo(&frames_to_output,
582 WebSocketFrameHeader::kOpCodeText,
584 AppendTo(&frames_to_output,
585 WebSocketFrameHeader::kOpCodeContinuation,
587 ReadFramesStub stub(OK, &frames_to_output);
588 CompletionCallback callback;
589 ScopedVector<WebSocketFrame> frames;
593 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
594 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
596 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
597 ASSERT_EQ(2u, frames.size());
598 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
599 EXPECT_FALSE(frames[0]->header.final);
600 EXPECT_FALSE(frames[0]->header.reserved1);
601 EXPECT_EQ("", ToString(frames[0]));
602 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
603 frames[1]->header.opcode);
604 EXPECT_TRUE(frames[1]->header.final);
605 EXPECT_FALSE(frames[1]->header.reserved1);
606 EXPECT_EQ("", ToString(frames[1]));
609 TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
610 ScopedVector<WebSocketFrame> frames_to_output;
611 AppendTo(&frames_to_output,
612 WebSocketFrameHeader::kOpCodeText,
614 std::string("\x02\x00", 1));
615 AppendTo(&frames_to_output,
616 WebSocketFrameHeader::kOpCodeContinuation,
618 ReadFramesStub stub(OK, &frames_to_output);
619 CompletionCallback callback;
620 ScopedVector<WebSocketFrame> frames;
624 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
625 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
627 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
628 ASSERT_EQ(1u, frames.size());
629 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
630 EXPECT_TRUE(frames[0]->header.final);
631 EXPECT_FALSE(frames[0]->header.reserved1);
632 EXPECT_EQ("", ToString(frames[0]));
635 TEST_F(WebSocketDeflateStreamTest,
636 ReadCompressedFrameFollowedByEmptyFrame) {
637 const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
638 ScopedVector<WebSocketFrame> frames_to_output;
639 AppendTo(&frames_to_output,
640 WebSocketFrameHeader::kOpCodeText,
643 AppendTo(&frames_to_output,
644 WebSocketFrameHeader::kOpCodeContinuation,
646 ReadFramesStub stub(OK, &frames_to_output);
647 CompletionCallback callback;
648 ScopedVector<WebSocketFrame> frames;
652 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
653 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
655 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
656 ASSERT_EQ(1u, frames.size());
657 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
658 EXPECT_TRUE(frames[0]->header.final);
659 EXPECT_FALSE(frames[0]->header.reserved1);
660 EXPECT_EQ("Hello", ToString(frames[0]));
663 TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
664 const std::string data1("\xf2\x48\xcd", 3);
665 const std::string data2("\xc9\xc9\x07\x00", 4);
666 ScopedVector<WebSocketFrame> frames_to_output;
667 AppendTo(&frames_to_output,
668 WebSocketFrameHeader::kOpCodeText,
671 AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodePing, kFinal);
672 AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2);
673 ReadFramesStub stub(OK, &frames_to_output);
674 CompletionCallback callback;
675 ScopedVector<WebSocketFrame> frames;
679 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
680 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
682 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
683 ASSERT_EQ(2u, frames.size());
684 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames[0]->header.opcode);
685 EXPECT_TRUE(frames[0]->header.final);
686 EXPECT_FALSE(frames[0]->header.reserved1);
687 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
688 EXPECT_TRUE(frames[1]->header.final);
689 EXPECT_FALSE(frames[1]->header.reserved1);
690 EXPECT_EQ("Hello", ToString(frames[1]));
693 TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) {
694 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
695 deflater.Initialize(kWindowBits);
696 const size_t kSize = kChunkSize * 3;
697 const std::string original_data(kSize, 'a');
698 deflater.AddBytes(original_data.data(), original_data.size());
701 ScopedVector<WebSocketFrame> frames_to_output;
702 AppendTo(&frames_to_output,
703 WebSocketFrameHeader::kOpCodeBinary,
705 ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
707 ReadFramesStub stub(OK, &frames_to_output);
708 CompletionCallback callback;
709 ScopedVector<WebSocketFrame> frames;
712 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
713 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
716 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
717 ASSERT_EQ(3u, frames.size());
718 EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
719 EXPECT_FALSE(frames[0]->header.final);
720 EXPECT_FALSE(frames[0]->header.reserved1);
721 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
722 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
723 frames[1]->header.opcode);
724 EXPECT_FALSE(frames[1]->header.final);
725 EXPECT_FALSE(frames[1]->header.reserved1);
726 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[1]->header.payload_length));
727 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
728 frames[2]->header.opcode);
729 EXPECT_TRUE(frames[2]->header.final);
730 EXPECT_FALSE(frames[2]->header.reserved1);
731 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[2]->header.payload_length));
732 EXPECT_EQ(original_data,
733 ToString(frames[0]) + ToString(frames[1]) + ToString(frames[2]));
736 TEST_F(WebSocketDeflateStreamTest,
737 Reserved1TurnsOnDuringReadingCompressedContinuationFrame) {
738 const std::string data1("\xf2\x48\xcd", 3);
739 const std::string data2("\xc9\xc9\x07\x00", 4);
740 ScopedVector<WebSocketFrame> frames_to_output;
741 AppendTo(&frames_to_output,
742 WebSocketFrameHeader::kOpCodeText,
745 AppendTo(&frames_to_output,
746 WebSocketFrameHeader::kOpCodeContinuation,
749 ReadFramesStub stub(OK, &frames_to_output);
750 CompletionCallback callback;
751 ScopedVector<WebSocketFrame> frames;
755 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
756 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
758 ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
759 deflate_stream_->ReadFrames(&frames, callback));
762 TEST_F(WebSocketDeflateStreamTest,
763 Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) {
764 ScopedVector<WebSocketFrame> frames_to_output;
765 AppendTo(&frames_to_output,
766 WebSocketFrameHeader::kOpCodeText,
769 AppendTo(&frames_to_output,
770 WebSocketFrameHeader::kOpCodeContinuation,
773 ReadFramesStub stub(OK, &frames_to_output);
774 CompletionCallback callback;
775 ScopedVector<WebSocketFrame> frames;
779 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
780 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
782 ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
783 deflate_stream_->ReadFrames(&frames, callback));
786 TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
787 ScopedVector<WebSocketFrame> frames_to_output;
788 AppendTo(&frames_to_output,
789 WebSocketFrameHeader::kOpCodeText,
792 "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x31\x04\x00", 13));
793 AppendTo(&frames_to_output,
794 WebSocketFrameHeader::kOpCodeText,
796 std::string("\x4a\x86\x33\x8d\x00\x00", 6));
797 ReadFramesStub stub(OK, &frames_to_output);
798 CompletionCallback callback;
799 ScopedVector<WebSocketFrame> frames;
803 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
804 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
806 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
807 ASSERT_EQ(2u, frames.size());
808 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
809 EXPECT_TRUE(frames[0]->header.final);
810 EXPECT_FALSE(frames[0]->header.reserved1);
811 EXPECT_EQ("compressed1", ToString(frames[0]));
812 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
813 EXPECT_TRUE(frames[1]->header.final);
814 EXPECT_FALSE(frames[1]->header.reserved1);
815 EXPECT_EQ("compressed2", ToString(frames[1]));
818 TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
819 ScopedVector<WebSocketFrame> frames_to_output;
820 AppendTo(&frames_to_output,
821 WebSocketFrameHeader::kOpCodeText,
824 AppendTo(&frames_to_output,
825 WebSocketFrameHeader::kOpCodeText,
828 ReadFramesStub stub(OK, &frames_to_output);
829 CompletionCallback callback;
830 ScopedVector<WebSocketFrame> frames;
834 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
835 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
837 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
838 ASSERT_EQ(2u, frames.size());
839 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
840 EXPECT_TRUE(frames[0]->header.final);
841 EXPECT_FALSE(frames[0]->header.reserved1);
842 EXPECT_EQ("uncompressed1", ToString(frames[0]));
843 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
844 EXPECT_TRUE(frames[1]->header.final);
845 EXPECT_FALSE(frames[1]->header.reserved1);
846 EXPECT_EQ("uncompressed2", ToString(frames[1]));
849 TEST_F(WebSocketDeflateStreamTest,
850 ReadCompressedMessageThenUncompressedMessage) {
851 ScopedVector<WebSocketFrame> frames_to_output;
852 AppendTo(&frames_to_output,
853 WebSocketFrameHeader::kOpCodeText,
856 "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
857 AppendTo(&frames_to_output,
858 WebSocketFrameHeader::kOpCodeText,
861 ReadFramesStub stub(OK, &frames_to_output);
862 CompletionCallback callback;
863 ScopedVector<WebSocketFrame> frames;
867 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
868 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
870 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
871 ASSERT_EQ(2u, frames.size());
872 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
873 EXPECT_TRUE(frames[0]->header.final);
874 EXPECT_FALSE(frames[0]->header.reserved1);
875 EXPECT_EQ("compressed", ToString(frames[0]));
876 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
877 EXPECT_TRUE(frames[1]->header.final);
878 EXPECT_FALSE(frames[1]->header.reserved1);
879 EXPECT_EQ("uncompressed", ToString(frames[1]));
882 TEST_F(WebSocketDeflateStreamTest,
883 ReadUncompressedMessageThenCompressedMessage) {
884 ScopedVector<WebSocketFrame> frames_to_output;
885 AppendTo(&frames_to_output,
886 WebSocketFrameHeader::kOpCodeText,
889 AppendTo(&frames_to_output,
890 WebSocketFrameHeader::kOpCodeText,
893 "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
894 ReadFramesStub stub(OK, &frames_to_output);
895 CompletionCallback callback;
896 ScopedVector<WebSocketFrame> frames;
900 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
901 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
903 ASSERT_EQ(OK, deflate_stream_->ReadFrames(&frames, callback));
904 ASSERT_EQ(2u, frames.size());
905 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
906 EXPECT_TRUE(frames[0]->header.final);
907 EXPECT_FALSE(frames[0]->header.reserved1);
908 EXPECT_EQ("uncompressed", ToString(frames[0]));
909 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
910 EXPECT_TRUE(frames[1]->header.final);
911 EXPECT_FALSE(frames[1]->header.reserved1);
912 EXPECT_EQ("compressed", ToString(frames[1]));
915 TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
916 ScopedVector<WebSocketFrame> frames;
917 CompletionCallback callback;
920 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)).Times(0);
922 EXPECT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
925 TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
926 ScopedVector<WebSocketFrame> frames;
927 CompletionCallback callback;
930 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
931 .WillOnce(Return(ERR_FAILED));
934 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello");
935 predictor_->AddFramesToBeInput(frames);
936 EXPECT_EQ(ERR_FAILED, deflate_stream_->WriteFrames(&frames, callback));
940 TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
941 ScopedVector<WebSocketFrame> frames;
942 CompletionCallback callback;
943 WriteFramesStub stub(predictor_, OK);
944 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
945 predictor_->AddFramesToBeInput(frames);
948 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
949 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
951 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
952 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
953 ASSERT_EQ(1u, frames_passed.size());
954 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
955 EXPECT_TRUE(frames_passed[0]->header.final);
956 EXPECT_TRUE(frames_passed[0]->header.reserved1);
957 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
958 ToString(frames_passed[0]));
961 TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
962 WriteFramesStub stub(predictor_, ERR_IO_PENDING);
963 MockCallback mock_callback, checkpoint;
964 CompletionCallback callback =
965 base::Bind(&MockCallback::Call, base::Unretained(&mock_callback));
966 ScopedVector<WebSocketFrame> frames;
969 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
970 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
971 EXPECT_CALL(checkpoint, Call(0));
972 EXPECT_CALL(mock_callback, Call(OK));
974 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
975 predictor_->AddFramesToBeInput(frames);
976 ASSERT_EQ(ERR_IO_PENDING, deflate_stream_->WriteFrames(&frames, callback));
979 stub.callback().Run(OK);
981 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
982 ASSERT_EQ(1u, frames_passed.size());
983 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
984 EXPECT_TRUE(frames_passed[0]->header.final);
985 EXPECT_TRUE(frames_passed[0]->header.reserved1);
986 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
987 ToString(frames_passed[0]));
990 TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
991 ScopedVector<WebSocketFrame> frames;
992 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
993 AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
994 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
995 predictor_->AddFramesToBeInput(frames);
996 WriteFramesStub stub(predictor_, OK);
997 CompletionCallback callback;
1001 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1002 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1004 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1005 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1006 ASSERT_EQ(2u, frames_passed.size());
1007 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
1008 EXPECT_TRUE(frames_passed[0]->header.final);
1009 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1010 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1011 EXPECT_TRUE(frames_passed[1]->header.final);
1012 EXPECT_TRUE(frames_passed[1]->header.reserved1);
1013 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1014 ToString(frames_passed[1]));
1017 TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
1018 ScopedVector<WebSocketFrame> frames;
1019 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
1020 predictor_->AddFramesToBeInput(frames);
1021 WriteFramesStub stub(predictor_, OK);
1022 CompletionCallback callback;
1026 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1027 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1029 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1030 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1031 ASSERT_EQ(1u, frames_passed.size());
1032 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1033 EXPECT_TRUE(frames_passed[0]->header.final);
1034 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1035 EXPECT_EQ(std::string("\x00", 1), ToString(frames_passed[0]));
1038 TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
1039 ScopedVector<WebSocketFrame> frames;
1040 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
1041 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
1042 predictor_->AddFramesToBeInput(frames);
1043 WriteFramesStub stub(predictor_, OK);
1044 CompletionCallback callback;
1046 predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE);
1050 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1051 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1053 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1054 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1055 ASSERT_EQ(2u, frames_passed.size());
1056 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1057 EXPECT_FALSE(frames_passed[0]->header.final);
1058 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1059 EXPECT_EQ("AAAA", ToString(frames_passed[0]));
1060 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1061 frames_passed[1]->header.opcode);
1062 EXPECT_TRUE(frames_passed[1]->header.final);
1063 EXPECT_FALSE(frames_passed[1]->header.reserved1);
1064 EXPECT_EQ("AAA", ToString(frames_passed[1]));
1067 TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
1068 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
1069 LinearCongruentialGenerator lcg(133);
1070 WriteFramesStub stub(predictor_, OK);
1071 CompletionCallback callback;
1072 const size_t size = 1024;
1076 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1077 .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
1079 ScopedVector<WebSocketFrame> total_compressed_frames;
1081 deflater.Initialize(kWindowBits);
1083 bool is_final = (total_compressed_frames.size() >= 2);
1084 ScopedVector<WebSocketFrame> frames;
1086 for (size_t i = 0; i < size; ++i)
1087 data += static_cast<char>(lcg.Generate());
1088 deflater.AddBytes(data.data(), data.size());
1089 FrameFlag flag = is_final ? kFinal : kNoFlag;
1090 AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
1091 predictor_->AddFramesToBeInput(frames);
1092 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1093 total_compressed_frames.insert(total_compressed_frames.end(),
1094 stub.frames()->begin(),
1095 stub.frames()->end());
1096 stub.frames()->weak_clear();
1101 std::string total_deflated;
1102 for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
1103 WebSocketFrame* frame = total_compressed_frames[i];
1104 const WebSocketFrameHeader& header = frame->header;
1106 EXPECT_EQ(header.kOpCodeContinuation, header.opcode);
1107 EXPECT_FALSE(header.reserved1);
1109 EXPECT_EQ(header.kOpCodeBinary, header.opcode);
1110 EXPECT_TRUE(header.reserved1);
1112 const bool is_final_frame = (i + 1 == total_compressed_frames.size());
1113 EXPECT_EQ(is_final_frame, header.final);
1114 if (!is_final_frame)
1115 EXPECT_GT(header.payload_length, 0ul);
1116 total_deflated += ToString(frame);
1118 EXPECT_EQ(total_deflated,
1119 ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
1122 TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
1123 ScopedVector<WebSocketFrame> frames;
1124 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1125 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1126 predictor_->AddFramesToBeInput(frames);
1127 WriteFramesStub stub(predictor_, OK);
1128 CompletionCallback callback;
1132 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1133 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1135 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1136 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1137 ASSERT_EQ(2u, frames_passed.size());
1138 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1139 EXPECT_TRUE(frames_passed[0]->header.final);
1140 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1141 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1142 ToString(frames_passed[0]));
1143 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1144 EXPECT_TRUE(frames_passed[1]->header.final);
1145 EXPECT_TRUE(frames_passed[1]->header.reserved1);
1146 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1]));
1149 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1150 WriteMultipleMessages) {
1151 ScopedVector<WebSocketFrame> frames;
1152 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1153 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1154 predictor_->AddFramesToBeInput(frames);
1155 WriteFramesStub stub(predictor_, OK);
1156 CompletionCallback callback;
1160 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1161 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1163 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1164 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1165 ASSERT_EQ(2u, frames_passed.size());
1166 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1167 EXPECT_TRUE(frames_passed[0]->header.final);
1168 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1169 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1170 ToString(frames_passed[0]));
1171 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1172 EXPECT_TRUE(frames_passed[1]->header.final);
1173 EXPECT_TRUE(frames_passed[1]->header.reserved1);
1174 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1175 ToString(frames_passed[1]));
1178 // In order to check the stream works correctly for multiple
1179 // "PossiblyCompressedMessage"s, we test various messages at one test case.
1180 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1181 WritePossiblyCompressMessages) {
1182 ScopedVector<WebSocketFrame> frames;
1183 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
1184 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
1185 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
1186 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA");
1187 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX");
1188 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY");
1189 predictor_->AddFramesToBeInput(frames);
1190 WriteFramesStub stub(predictor_, OK);
1191 CompletionCallback callback;
1192 predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE);
1196 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
1197 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1199 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames, callback));
1200 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1201 ASSERT_EQ(5u, frames_passed.size());
1203 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1204 EXPECT_FALSE(frames_passed[0]->header.final);
1205 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1206 EXPECT_EQ("He", ToString(frames_passed[0]));
1207 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1208 frames_passed[1]->header.opcode);
1209 EXPECT_TRUE(frames_passed[1]->header.final);
1210 EXPECT_FALSE(frames_passed[1]->header.reserved1);
1211 EXPECT_EQ("llo", ToString(frames_passed[1]));
1213 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode);
1214 EXPECT_TRUE(frames_passed[2]->header.final);
1215 EXPECT_TRUE(frames_passed[2]->header.reserved1);
1216 EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6),
1217 ToString(frames_passed[2]));
1219 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode);
1220 EXPECT_FALSE(frames_passed[3]->header.final);
1221 EXPECT_FALSE(frames_passed[3]->header.reserved1);
1222 EXPECT_EQ("XX", ToString(frames_passed[3]));
1223 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1224 frames_passed[4]->header.opcode);
1225 EXPECT_TRUE(frames_passed[4]->header.final);
1226 EXPECT_FALSE(frames_passed[4]->header.reserved1);
1227 EXPECT_EQ("YY", ToString(frames_passed[4]));
1230 // This is based on the similar test from websocket_deflater_test.cc
1231 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits8) {
1232 SetUpWithWindowBits(8);
1233 CompletionCallback callback;
1234 AddCompressibleFrameString();
1235 WriteFramesStub stub(predictor_, OK);
1238 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1239 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1241 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
1242 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1243 ASSERT_EQ(1u, frames_passed.size());
1244 EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
1245 "(?7\xb3\x34\x17\x00", 21),
1246 ToString(frames_passed[0]));
1249 // The same input with window_bits=10 returns smaller output.
1250 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits10) {
1251 SetUpWithWindowBits(10);
1252 CompletionCallback callback;
1253 AddCompressibleFrameString();
1254 WriteFramesStub stub(predictor_, OK);
1257 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
1258 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1260 ASSERT_EQ(OK, deflate_stream_->WriteFrames(&frames_, callback));
1261 const ScopedVector<WebSocketFrame>& frames_passed = *stub.frames();
1262 ASSERT_EQ(1u, frames_passed.size());
1264 std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
1265 ToString(frames_passed[0]));