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 // This is a regression test for crbug.com/343506.
916 TEST_F(WebSocketDeflateStreamTest
, ReadEmptyAsyncFrame
) {
917 ScopedVector
<ReadFramesStub
> stub_vector
;
918 stub_vector
.push_back(new ReadFramesStub(ERR_IO_PENDING
));
919 stub_vector
.push_back(new ReadFramesStub(ERR_IO_PENDING
));
920 MockCallback mock_callback
;
921 CompletionCallback callback
=
922 base::Bind(&MockCallback::Call
, base::Unretained(&mock_callback
));
923 ScopedVector
<WebSocketFrame
> frames
;
927 EXPECT_CALL(*mock_stream_
, ReadFrames(&frames
, _
))
928 .WillOnce(Invoke(stub_vector
[0], &ReadFramesStub::Call
));
930 EXPECT_CALL(*mock_stream_
, ReadFrames(&frames
, _
))
931 .WillOnce(Invoke(stub_vector
[1], &ReadFramesStub::Call
));
933 EXPECT_CALL(mock_callback
, Call(OK
));
936 ASSERT_EQ(ERR_IO_PENDING
, deflate_stream_
->ReadFrames(&frames
, callback
));
937 AppendTo(stub_vector
[0]->frames_passed(),
938 WebSocketFrameHeader::kOpCodeText
,
941 stub_vector
[0]->callback().Run(OK
);
942 AppendTo(stub_vector
[1]->frames_passed(),
943 WebSocketFrameHeader::kOpCodeContinuation
,
945 std::string("\x02\x00"));
946 stub_vector
[1]->callback().Run(OK
);
947 ASSERT_EQ(1u, frames
.size());
948 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames
[0]->header
.opcode
);
949 EXPECT_EQ("", ToString(frames
[0]));
952 TEST_F(WebSocketDeflateStreamTest
, WriteEmpty
) {
953 ScopedVector
<WebSocketFrame
> frames
;
954 CompletionCallback callback
;
957 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
)).Times(0);
959 EXPECT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
962 TEST_F(WebSocketDeflateStreamTest
, WriteFailedImmediately
) {
963 ScopedVector
<WebSocketFrame
> frames
;
964 CompletionCallback callback
;
967 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
968 .WillOnce(Return(ERR_FAILED
));
971 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "hello");
972 predictor_
->AddFramesToBeInput(frames
);
973 EXPECT_EQ(ERR_FAILED
, deflate_stream_
->WriteFrames(&frames
, callback
));
977 TEST_F(WebSocketDeflateStreamTest
, WriteFrameImmediately
) {
978 ScopedVector
<WebSocketFrame
> frames
;
979 CompletionCallback callback
;
980 WriteFramesStub
stub(predictor_
, OK
);
981 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "Hello");
982 predictor_
->AddFramesToBeInput(frames
);
985 EXPECT_CALL(*mock_stream_
, WriteFrames(_
, _
))
986 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
988 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
989 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
990 ASSERT_EQ(1u, frames_passed
.size());
991 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
992 EXPECT_TRUE(frames_passed
[0]->header
.final
);
993 EXPECT_TRUE(frames_passed
[0]->header
.reserved1
);
994 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
995 ToString(frames_passed
[0]));
998 TEST_F(WebSocketDeflateStreamTest
, WriteFrameAsync
) {
999 WriteFramesStub
stub(predictor_
, ERR_IO_PENDING
);
1000 MockCallback mock_callback
, checkpoint
;
1001 CompletionCallback callback
=
1002 base::Bind(&MockCallback::Call
, base::Unretained(&mock_callback
));
1003 ScopedVector
<WebSocketFrame
> frames
;
1006 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1007 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1008 EXPECT_CALL(checkpoint
, Call(0));
1009 EXPECT_CALL(mock_callback
, Call(OK
));
1011 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "Hello");
1012 predictor_
->AddFramesToBeInput(frames
);
1013 ASSERT_EQ(ERR_IO_PENDING
, deflate_stream_
->WriteFrames(&frames
, callback
));
1016 stub
.callback().Run(OK
);
1018 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1019 ASSERT_EQ(1u, frames_passed
.size());
1020 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
1021 EXPECT_TRUE(frames_passed
[0]->header
.final
);
1022 EXPECT_TRUE(frames_passed
[0]->header
.reserved1
);
1023 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1024 ToString(frames_passed
[0]));
1027 TEST_F(WebSocketDeflateStreamTest
, WriteControlFrameBetweenDataFrames
) {
1028 ScopedVector
<WebSocketFrame
> frames
;
1029 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kNoFlag
, "Hel");
1030 AppendTo(&frames
, WebSocketFrameHeader::kOpCodePing
, kFinal
);
1031 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeContinuation
, kFinal
, "lo");
1032 predictor_
->AddFramesToBeInput(frames
);
1033 WriteFramesStub
stub(predictor_
, OK
);
1034 CompletionCallback callback
;
1038 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1039 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1041 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1042 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1043 ASSERT_EQ(2u, frames_passed
.size());
1044 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing
, frames_passed
[0]->header
.opcode
);
1045 EXPECT_TRUE(frames_passed
[0]->header
.final
);
1046 EXPECT_FALSE(frames_passed
[0]->header
.reserved1
);
1047 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[1]->header
.opcode
);
1048 EXPECT_TRUE(frames_passed
[1]->header
.final
);
1049 EXPECT_TRUE(frames_passed
[1]->header
.reserved1
);
1050 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1051 ToString(frames_passed
[1]));
1054 TEST_F(WebSocketDeflateStreamTest
, WriteEmptyMessage
) {
1055 ScopedVector
<WebSocketFrame
> frames
;
1056 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
);
1057 predictor_
->AddFramesToBeInput(frames
);
1058 WriteFramesStub
stub(predictor_
, OK
);
1059 CompletionCallback callback
;
1063 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1064 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1066 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1067 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1068 ASSERT_EQ(1u, frames_passed
.size());
1069 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
1070 EXPECT_TRUE(frames_passed
[0]->header
.final
);
1071 EXPECT_TRUE(frames_passed
[0]->header
.reserved1
);
1072 EXPECT_EQ(std::string("\x00", 1), ToString(frames_passed
[0]));
1075 TEST_F(WebSocketDeflateStreamTest
, WriteUncompressedMessage
) {
1076 ScopedVector
<WebSocketFrame
> frames
;
1077 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kNoFlag
, "AAAA");
1078 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeContinuation
, kFinal
, "AAA");
1079 predictor_
->AddFramesToBeInput(frames
);
1080 WriteFramesStub
stub(predictor_
, OK
);
1081 CompletionCallback callback
;
1083 predictor_
->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE
);
1087 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1088 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1090 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1091 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1092 ASSERT_EQ(2u, frames_passed
.size());
1093 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
1094 EXPECT_FALSE(frames_passed
[0]->header
.final
);
1095 EXPECT_FALSE(frames_passed
[0]->header
.reserved1
);
1096 EXPECT_EQ("AAAA", ToString(frames_passed
[0]));
1097 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation
,
1098 frames_passed
[1]->header
.opcode
);
1099 EXPECT_TRUE(frames_passed
[1]->header
.final
);
1100 EXPECT_FALSE(frames_passed
[1]->header
.reserved1
);
1101 EXPECT_EQ("AAA", ToString(frames_passed
[1]));
1104 TEST_F(WebSocketDeflateStreamTest
, LargeDeflatedFramesShouldBeSplit
) {
1105 WebSocketDeflater
deflater(WebSocketDeflater::TAKE_OVER_CONTEXT
);
1106 LinearCongruentialGenerator
lcg(133);
1107 WriteFramesStub
stub(predictor_
, OK
);
1108 CompletionCallback callback
;
1109 const size_t size
= 1024;
1113 EXPECT_CALL(*mock_stream_
, WriteFrames(_
, _
))
1114 .WillRepeatedly(Invoke(&stub
, &WriteFramesStub::Call
));
1116 ScopedVector
<WebSocketFrame
> total_compressed_frames
;
1118 deflater
.Initialize(kWindowBits
);
1120 bool is_final
= (total_compressed_frames
.size() >= 2);
1121 ScopedVector
<WebSocketFrame
> frames
;
1123 for (size_t i
= 0; i
< size
; ++i
)
1124 data
+= static_cast<char>(lcg
.Generate());
1125 deflater
.AddBytes(data
.data(), data
.size());
1126 FrameFlag flag
= is_final
? kFinal
: kNoFlag
;
1127 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeBinary
, flag
, data
);
1128 predictor_
->AddFramesToBeInput(frames
);
1129 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1130 total_compressed_frames
.insert(total_compressed_frames
.end(),
1131 stub
.frames()->begin(),
1132 stub
.frames()->end());
1133 stub
.frames()->weak_clear();
1138 std::string total_deflated
;
1139 for (size_t i
= 0; i
< total_compressed_frames
.size(); ++i
) {
1140 WebSocketFrame
* frame
= total_compressed_frames
[i
];
1141 const WebSocketFrameHeader
& header
= frame
->header
;
1143 EXPECT_EQ(header
.kOpCodeContinuation
, header
.opcode
);
1144 EXPECT_FALSE(header
.reserved1
);
1146 EXPECT_EQ(header
.kOpCodeBinary
, header
.opcode
);
1147 EXPECT_TRUE(header
.reserved1
);
1149 const bool is_final_frame
= (i
+ 1 == total_compressed_frames
.size());
1150 EXPECT_EQ(is_final_frame
, header
.final
);
1151 if (!is_final_frame
)
1152 EXPECT_GT(header
.payload_length
, 0ul);
1153 total_deflated
+= ToString(frame
);
1155 EXPECT_EQ(total_deflated
,
1156 ToString(deflater
.GetOutput(deflater
.CurrentOutputSize())));
1159 TEST_F(WebSocketDeflateStreamTest
, WriteMultipleMessages
) {
1160 ScopedVector
<WebSocketFrame
> frames
;
1161 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "Hello");
1162 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "Hello");
1163 predictor_
->AddFramesToBeInput(frames
);
1164 WriteFramesStub
stub(predictor_
, OK
);
1165 CompletionCallback callback
;
1169 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1170 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1172 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1173 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1174 ASSERT_EQ(2u, frames_passed
.size());
1175 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
1176 EXPECT_TRUE(frames_passed
[0]->header
.final
);
1177 EXPECT_TRUE(frames_passed
[0]->header
.reserved1
);
1178 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1179 ToString(frames_passed
[0]));
1180 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[1]->header
.opcode
);
1181 EXPECT_TRUE(frames_passed
[1]->header
.final
);
1182 EXPECT_TRUE(frames_passed
[1]->header
.reserved1
);
1183 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed
[1]));
1186 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest
,
1187 WriteMultipleMessages
) {
1188 ScopedVector
<WebSocketFrame
> frames
;
1189 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "Hello");
1190 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kFinal
, "Hello");
1191 predictor_
->AddFramesToBeInput(frames
);
1192 WriteFramesStub
stub(predictor_
, OK
);
1193 CompletionCallback callback
;
1197 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1198 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1200 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1201 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1202 ASSERT_EQ(2u, frames_passed
.size());
1203 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
1204 EXPECT_TRUE(frames_passed
[0]->header
.final
);
1205 EXPECT_TRUE(frames_passed
[0]->header
.reserved1
);
1206 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1207 ToString(frames_passed
[0]));
1208 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[1]->header
.opcode
);
1209 EXPECT_TRUE(frames_passed
[1]->header
.final
);
1210 EXPECT_TRUE(frames_passed
[1]->header
.reserved1
);
1211 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1212 ToString(frames_passed
[1]));
1215 // In order to check the stream works correctly for multiple
1216 // "PossiblyCompressedMessage"s, we test various messages at one test case.
1217 TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest
,
1218 WritePossiblyCompressMessages
) {
1219 ScopedVector
<WebSocketFrame
> frames
;
1220 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kNoFlag
, "He");
1221 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeContinuation
, kFinal
, "llo");
1222 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kNoFlag
, "AAAAAAAAAA");
1223 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeContinuation
, kFinal
, "AA");
1224 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeText
, kNoFlag
, "XX");
1225 AppendTo(&frames
, WebSocketFrameHeader::kOpCodeContinuation
, kFinal
, "YY");
1226 predictor_
->AddFramesToBeInput(frames
);
1227 WriteFramesStub
stub(predictor_
, OK
);
1228 CompletionCallback callback
;
1229 predictor_
->set_result(WebSocketDeflatePredictor::TRY_DEFLATE
);
1233 EXPECT_CALL(*mock_stream_
, WriteFrames(&frames
, _
))
1234 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1236 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames
, callback
));
1237 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1238 ASSERT_EQ(5u, frames_passed
.size());
1240 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[0]->header
.opcode
);
1241 EXPECT_FALSE(frames_passed
[0]->header
.final
);
1242 EXPECT_FALSE(frames_passed
[0]->header
.reserved1
);
1243 EXPECT_EQ("He", ToString(frames_passed
[0]));
1244 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation
,
1245 frames_passed
[1]->header
.opcode
);
1246 EXPECT_TRUE(frames_passed
[1]->header
.final
);
1247 EXPECT_FALSE(frames_passed
[1]->header
.reserved1
);
1248 EXPECT_EQ("llo", ToString(frames_passed
[1]));
1250 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[2]->header
.opcode
);
1251 EXPECT_TRUE(frames_passed
[2]->header
.final
);
1252 EXPECT_TRUE(frames_passed
[2]->header
.reserved1
);
1253 EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6),
1254 ToString(frames_passed
[2]));
1256 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText
, frames_passed
[3]->header
.opcode
);
1257 EXPECT_FALSE(frames_passed
[3]->header
.final
);
1258 EXPECT_FALSE(frames_passed
[3]->header
.reserved1
);
1259 EXPECT_EQ("XX", ToString(frames_passed
[3]));
1260 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation
,
1261 frames_passed
[4]->header
.opcode
);
1262 EXPECT_TRUE(frames_passed
[4]->header
.final
);
1263 EXPECT_FALSE(frames_passed
[4]->header
.reserved1
);
1264 EXPECT_EQ("YY", ToString(frames_passed
[4]));
1267 // This is based on the similar test from websocket_deflater_test.cc
1268 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest
, WindowBits8
) {
1269 SetUpWithWindowBits(8);
1270 CompletionCallback callback
;
1271 AddCompressibleFrameString();
1272 WriteFramesStub
stub(predictor_
, OK
);
1275 EXPECT_CALL(*mock_stream_
, WriteFrames(_
, _
))
1276 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1278 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames_
, callback
));
1279 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1280 ASSERT_EQ(1u, frames_passed
.size());
1281 EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
1282 "(?7\xb3\x34\x17\x00", 21),
1283 ToString(frames_passed
[0]));
1286 // The same input with window_bits=10 returns smaller output.
1287 TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest
, WindowBits10
) {
1288 SetUpWithWindowBits(10);
1289 CompletionCallback callback
;
1290 AddCompressibleFrameString();
1291 WriteFramesStub
stub(predictor_
, OK
);
1294 EXPECT_CALL(*mock_stream_
, WriteFrames(_
, _
))
1295 .WillOnce(Invoke(&stub
, &WriteFramesStub::Call
));
1297 ASSERT_EQ(OK
, deflate_stream_
->WriteFrames(&frames_
, callback
));
1298 const ScopedVector
<WebSocketFrame
>& frames_passed
= *stub
.frames();
1299 ASSERT_EQ(1u, frames_passed
.size());
1301 std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
1302 ToString(frames_passed
[0]));