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