blob: 829f0e52b3aa49fd39b82ffa2018cafc980a36fe [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2013 The Chromium Authors
[email protected]ce9f7ffd2013-10-11 06:04:112// 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
tfarinaea94afc232015-10-20 04:23:367#include <stddef.h>
[email protected]ce9f7ffd2013-10-11 06:04:118#include <stdint.h>
danakj9c5cab52016-04-16 00:54:339
yhirano592ff7f2015-12-07 08:45:1910#include <iterator>
[email protected]ce9f7ffd2013-10-11 06:04:1111#include <string>
yhirano592ff7f2015-12-07 08:45:1912#include <utility>
13#include <vector>
[email protected]ce9f7ffd2013-10-11 06:04:1114
Brett Wilsonc6a0c822017-09-12 00:04:2915#include "base/containers/circular_deque.h"
Avi Drissman41c4a412023-01-11 22:45:3716#include "base/functional/bind.h"
17#include "base/functional/callback_helpers.h"
Bence Béky65623972018-03-05 15:31:5618#include "base/memory/ptr_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5219#include "base/memory/raw_ptr.h"
Bence Béky65623972018-03-05 15:31:5620#include "base/memory/scoped_refptr.h"
jbromanc5b4bd262017-01-18 20:49:1721#include "base/test/mock_callback.h"
[email protected]ce9f7ffd2013-10-11 06:04:1122#include "net/base/io_buffer.h"
23#include "net/base/net_errors.h"
Nanami Mikiyaab5e17d2022-02-07 07:39:4224#include "net/log/net_log_with_source.h"
robpercival214763f2016-07-01 23:27:0125#include "net/test/gtest_util.h"
yhirano8387aee2015-09-14 05:46:4926#include "net/websockets/websocket_deflate_parameters.h"
[email protected]ef735622013-10-30 14:28:1827#include "net/websockets/websocket_deflate_predictor.h"
[email protected]ce9f7ffd2013-10-11 06:04:1128#include "net/websockets/websocket_deflater.h"
29#include "net/websockets/websocket_frame.h"
30#include "net/websockets/websocket_inflater.h"
31#include "net/websockets/websocket_stream.h"
32#include "net/websockets/websocket_test_util.h"
33#include "testing/gmock/include/gmock/gmock.h"
34#include "testing/gtest/include/gtest/gtest.h"
[email protected]ce9f7ffd2013-10-11 06:04:1135
robpercival214763f2016-07-01 23:27:0136using net::test::IsError;
37using net::test::IsOk;
38
[email protected]ce9f7ffd2013-10-11 06:04:1139namespace net {
[email protected]ce9f7ffd2013-10-11 06:04:1140namespace {
41
[email protected]693ebf32013-10-23 13:47:0142using ::testing::_;
43using ::testing::InSequence;
44using ::testing::Invoke;
45using ::testing::Return;
[email protected]ce9f7ffd2013-10-11 06:04:1146
47typedef uint32_t FrameFlag;
48const FrameFlag kNoFlag = 0;
49const FrameFlag kFinal = 1;
50const FrameFlag kReserved1 = 2;
51// We don't define values for other flags because we don't need them.
52
53// The value must equal to the value of the corresponding
54// constant in websocket_deflate_stream.cc
55const size_t kChunkSize = 4 * 1024;
56const int kWindowBits = 15;
57
[email protected]ce9f7ffd2013-10-11 06:04:1158std::string ToString(IOBufferWithSize* buffer) {
59 return std::string(buffer->data(), buffer->size());
60}
61
62std::string ToString(const scoped_refptr<IOBufferWithSize>& buffer) {
63 return ToString(buffer.get());
64}
65
[email protected]ef735622013-10-30 14:28:1866std::string ToString(const WebSocketFrame* frame) {
Yoichi Osato05cd3642019-09-09 18:13:0867 return frame->payload
68 ? std::string(frame->payload, frame->header.payload_length)
69 : "";
[email protected]ce9f7ffd2013-10-11 06:04:1170}
71
danakj9c5cab52016-04-16 00:54:3372std::string ToString(const std::unique_ptr<WebSocketFrame>& frame) {
yhirano592ff7f2015-12-07 08:45:1973 return ToString(frame.get());
74}
75
[email protected]ce9f7ffd2013-10-11 06:04:1176class MockWebSocketStream : public WebSocketStream {
77 public:
Joshua Bell90829e32021-05-19 15:59:3978 MOCK_METHOD2(ReadFrames,
danakj9c5cab52016-04-16 00:54:3379 int(std::vector<std::unique_ptr<WebSocketFrame>>*,
Joshua Bell90829e32021-05-19 15:59:3980 CompletionOnceCallback));
81 MOCK_METHOD2(WriteFrames,
danakj9c5cab52016-04-16 00:54:3382 int(std::vector<std::unique_ptr<WebSocketFrame>>*,
Joshua Bell90829e32021-05-19 15:59:3983 CompletionOnceCallback));
Bence Békyf4f56e22018-07-17 02:00:0584
[email protected]ce9f7ffd2013-10-11 06:04:1185 MOCK_METHOD0(Close, void());
86 MOCK_CONST_METHOD0(GetSubProtocol, std::string());
87 MOCK_CONST_METHOD0(GetExtensions, std::string());
Nanami Mikiyaab5e17d2022-02-07 07:39:4288 MOCK_CONST_METHOD0(GetNetLogWithSource, NetLogWithSource&());
[email protected]ce9f7ffd2013-10-11 06:04:1189};
90
[email protected]ef735622013-10-30 14:28:1891// This mock class relies on some assumptions.
92// - RecordInputDataFrame is called after the corresponding WriteFrames
93// call.
94// - RecordWrittenDataFrame is called before writing the frame.
95class WebSocketDeflatePredictorMock : public WebSocketDeflatePredictor {
96 public:
Tsuyoshi Horoa0b9c0f2022-06-09 01:41:5197 WebSocketDeflatePredictorMock() = default;
Peter Boström293b1342021-09-22 17:31:4398
99 WebSocketDeflatePredictorMock(const WebSocketDeflatePredictorMock&) = delete;
100 WebSocketDeflatePredictorMock& operator=(
101 const WebSocketDeflatePredictorMock&) = delete;
102
dchengb03027d2014-10-21 12:00:20103 ~WebSocketDeflatePredictorMock() override {
[email protected]ef735622013-10-30 14:28:18104 // Verify whether all expectaions are consumed.
105 if (!frames_to_be_input_.empty()) {
106 ADD_FAILURE() << "There are missing frames to be input.";
107 return;
108 }
109 if (!frames_written_.empty()) {
110 ADD_FAILURE() << "There are extra written frames.";
111 return;
112 }
113 }
114
115 // WebSocketDeflatePredictor functions.
danakj9c5cab52016-04-16 00:54:33116 Result Predict(const std::vector<std::unique_ptr<WebSocketFrame>>& frames,
dchengb03027d2014-10-21 12:00:20117 size_t frame_index) override {
[email protected]ef735622013-10-30 14:28:18118 return result_;
119 }
dchengb03027d2014-10-21 12:00:20120 void RecordInputDataFrame(const WebSocketFrame* frame) override {
[email protected]ef735622013-10-30 14:28:18121 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
122 ADD_FAILURE() << "Control frames should not be recorded.";
123 return;
124 }
125 if (frame->header.reserved1) {
126 ADD_FAILURE() << "Input frame may not be compressed.";
127 return;
128 }
129 if (frames_to_be_input_.empty()) {
130 ADD_FAILURE() << "Unexpected input data frame";
131 return;
132 }
133 if (frame != frames_to_be_input_.front()) {
134 ADD_FAILURE() << "Input data frame does not match the expectation.";
135 return;
136 }
137 frames_to_be_input_.pop_front();
138 }
dchengb03027d2014-10-21 12:00:20139 void RecordWrittenDataFrame(const WebSocketFrame* frame) override {
[email protected]ef735622013-10-30 14:28:18140 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode)) {
141 ADD_FAILURE() << "Control frames should not be recorded.";
142 return;
143 }
144 frames_written_.push_back(frame);
145 }
146
147 // Sets |result_| for the |Predict| return value.
148 void set_result(Result result) { result_ = result; }
149
150 // Adds |frame| as an expectation of future |RecordInputDataFrame| call.
151 void AddFrameToBeInput(const WebSocketFrame* frame) {
152 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
153 return;
154 frames_to_be_input_.push_back(frame);
155 }
156 // Verifies that |frame| is recorded in order.
157 void VerifySentFrame(const WebSocketFrame* frame) {
158 if (!WebSocketFrameHeader::IsKnownDataOpCode(frame->header.opcode))
159 return;
160 if (frames_written_.empty()) {
161 ADD_FAILURE() << "There are missing frames to be written.";
162 return;
163 }
164 if (frame != frames_written_.front()) {
165 ADD_FAILURE() << "Written data frame does not match the expectation.";
166 return;
167 }
168 frames_written_.pop_front();
169 }
yhirano592ff7f2015-12-07 08:45:19170 void AddFramesToBeInput(
danakj9c5cab52016-04-16 00:54:33171 const std::vector<std::unique_ptr<WebSocketFrame>>& frames) {
Tsuyoshi Horo17ef47d02022-06-30 10:58:27172 for (const auto& frame : frames)
173 AddFrameToBeInput(frame.get());
[email protected]ef735622013-10-30 14:28:18174 }
danakj9c5cab52016-04-16 00:54:33175 void VerifySentFrames(
176 const std::vector<std::unique_ptr<WebSocketFrame>>& frames) {
Tsuyoshi Horo17ef47d02022-06-30 10:58:27177 for (const auto& frame : frames)
178 VerifySentFrame(frame.get());
[email protected]ef735622013-10-30 14:28:18179 }
180 // Call this method in order to disable checks in the destructor when
181 // WriteFrames fails.
182 void Clear() {
183 frames_to_be_input_.clear();
184 frames_written_.clear();
185 }
186
187 private:
Tsuyoshi Horoa0b9c0f2022-06-09 01:41:51188 Result result_ = DEFLATE;
[email protected]ef735622013-10-30 14:28:18189 // Data frames which will be recorded by |RecordInputFrames|.
190 // Pushed by |AddFrameToBeInput| and popped and verified by
191 // |RecordInputFrames|.
Brett Wilsonc6a0c822017-09-12 00:04:29192 base::circular_deque<const WebSocketFrame*> frames_to_be_input_;
[email protected]ef735622013-10-30 14:28:18193 // Data frames recorded by |RecordWrittenFrames|.
194 // Pushed by |RecordWrittenFrames| and popped and verified by
195 // |VerifySentFrame|.
Brett Wilsonc6a0c822017-09-12 00:04:29196 base::circular_deque<const WebSocketFrame*> frames_written_;
[email protected]ef735622013-10-30 14:28:18197};
198
[email protected]ce9f7ffd2013-10-11 06:04:11199class WebSocketDeflateStreamTest : public ::testing::Test {
200 public:
Tsuyoshi Horo432981d52022-06-09 09:50:13201 WebSocketDeflateStreamTest() = default;
Chris Watkins28c2fdd2017-11-30 06:06:52202 ~WebSocketDeflateStreamTest() override = default;
[email protected]4a2ad812c2014-01-21 09:59:43203
dcheng67be2b1f2014-10-27 21:47:29204 void SetUp() override {
[email protected]4a2ad812c2014-01-21 09:59:43205 Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, kWindowBits);
206 }
207
208 protected:
209 // Initialize deflate_stream_ with the given parameters.
210 void Initialize(WebSocketDeflater::ContextTakeOverMode mode,
211 int window_bits) {
yhirano8387aee2015-09-14 05:46:49212 WebSocketDeflateParameters parameters;
213 if (mode == WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT) {
214 parameters.SetClientNoContextTakeOver();
215 }
216 parameters.SetClientMaxWindowBits(window_bits);
Tsuyoshi Horoc39623a82022-07-11 01:27:58217 auto mock_stream =
218 std::make_unique<testing::StrictMock<MockWebSocketStream>>();
219 auto predictor = std::make_unique<WebSocketDeflatePredictorMock>();
220 mock_stream_ = mock_stream.get();
221 predictor_ = predictor.get();
Bence Béky65623972018-03-05 15:31:56222 deflate_stream_ = std::make_unique<WebSocketDeflateStream>(
Tsuyoshi Horoc39623a82022-07-11 01:27:58223 std::move(mock_stream), parameters, std::move(predictor));
[email protected]ce9f7ffd2013-10-11 06:04:11224 }
[email protected]ce9f7ffd2013-10-11 06:04:11225
Yutaka Hirano76aacb202019-09-05 16:36:56226 void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
227 WebSocketFrameHeader::OpCode opcode,
228 FrameFlag flag) {
229 auto frame = std::make_unique<WebSocketFrame>(opcode);
230 frame->header.final = (flag & kFinal);
231 frame->header.reserved1 = (flag & kReserved1);
232 frames->push_back(std::move(frame));
233 }
234
235 void AppendTo(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
236 WebSocketFrameHeader::OpCode opcode,
237 FrameFlag flag,
238 const std::string& data) {
239 auto frame = std::make_unique<WebSocketFrame>(opcode);
240 frame->header.final = (flag & kFinal);
241 frame->header.reserved1 = (flag & kReserved1);
242 auto buffer = std::make_unique<char[]>(data.size());
243 memcpy(buffer.get(), data.c_str(), data.size());
Yoichi Osato05cd3642019-09-09 18:13:08244 frame->payload = buffer.get();
Yutaka Hirano76aacb202019-09-05 16:36:56245 data_buffers.push_back(std::move(buffer));
246 frame->header.payload_length = data.size();
247 frames->push_back(std::move(frame));
248 }
249
danakj9c5cab52016-04-16 00:54:33250 std::unique_ptr<WebSocketDeflateStream> deflate_stream_;
[email protected]ef735622013-10-30 14:28:18251 // Owned by |deflate_stream_|.
Tsuyoshi Horo432981d52022-06-09 09:50:13252 raw_ptr<MockWebSocketStream> mock_stream_ = nullptr;
[email protected]ef735622013-10-30 14:28:18253 // Owned by |deflate_stream_|.
Tsuyoshi Horo432981d52022-06-09 09:50:13254 raw_ptr<WebSocketDeflatePredictorMock> predictor_ = nullptr;
Yutaka Hirano76aacb202019-09-05 16:36:56255
256 // TODO(yoichio): Make this type std::vector<std::string>.
257 std::vector<std::unique_ptr<const char[]>> data_buffers;
[email protected]ce9f7ffd2013-10-11 06:04:11258};
259
[email protected]77c55ca32013-10-24 12:07:36260// Since WebSocketDeflater with DoNotTakeOverContext is well tested at
[email protected]ef735622013-10-30 14:28:18261// websocket_deflater_test.cc, we have only a few tests for this configuration
[email protected]77c55ca32013-10-24 12:07:36262// here.
263class WebSocketDeflateStreamWithDoNotTakeOverContextTest
[email protected]4a2ad812c2014-01-21 09:59:43264 : public WebSocketDeflateStreamTest {
[email protected]77c55ca32013-10-24 12:07:36265 public:
Chris Watkins28c2fdd2017-11-30 06:06:52266 WebSocketDeflateStreamWithDoNotTakeOverContextTest() = default;
267 ~WebSocketDeflateStreamWithDoNotTakeOverContextTest() override = default;
[email protected]77c55ca32013-10-24 12:07:36268
dcheng67be2b1f2014-10-27 21:47:29269 void SetUp() override {
[email protected]4a2ad812c2014-01-21 09:59:43270 Initialize(WebSocketDeflater::DO_NOT_TAKE_OVER_CONTEXT, kWindowBits);
271 }
272};
273
274class WebSocketDeflateStreamWithClientWindowBitsTest
275 : public WebSocketDeflateStreamTest {
276 public:
Chris Watkins28c2fdd2017-11-30 06:06:52277 WebSocketDeflateStreamWithClientWindowBitsTest() = default;
278 ~WebSocketDeflateStreamWithClientWindowBitsTest() override = default;
[email protected]4a2ad812c2014-01-21 09:59:43279
280 // Overridden to postpone the call to Initialize().
dcheng67be2b1f2014-10-27 21:47:29281 void SetUp() override {}
[email protected]4a2ad812c2014-01-21 09:59:43282
283 // This needs to be called explicitly from the tests.
284 void SetUpWithWindowBits(int window_bits) {
285 Initialize(WebSocketDeflater::TAKE_OVER_CONTEXT, window_bits);
286 }
287
288 // Add a frame which will be compressed to a smaller size if the window
289 // size is large enough.
290 void AddCompressibleFrameString() {
291 const std::string word = "Chromium";
292 const std::string payload = word + std::string(256, 'a') + word;
293 AppendTo(&frames_, WebSocketFrameHeader::kOpCodeText, kFinal, payload);
294 predictor_->AddFramesToBeInput(frames_);
295 }
296
[email protected]77c55ca32013-10-24 12:07:36297 protected:
danakj9c5cab52016-04-16 00:54:33298 std::vector<std::unique_ptr<WebSocketFrame>> frames_;
[email protected]77c55ca32013-10-24 12:07:36299};
300
[email protected]ce9f7ffd2013-10-11 06:04:11301// ReadFrameStub is a stub for WebSocketStream::ReadFrames.
302// It returns |result_| and |frames_to_output_| to the caller and
303// saves parameters to |frames_passed_| and |callback_|.
304class ReadFramesStub {
305 public:
306 explicit ReadFramesStub(int result) : result_(result) {}
307
yhirano592ff7f2015-12-07 08:45:19308 ReadFramesStub(int result,
danakj9c5cab52016-04-16 00:54:33309 std::vector<std::unique_ptr<WebSocketFrame>>* frames_to_output)
[email protected]ce9f7ffd2013-10-11 06:04:11310 : result_(result) {
311 frames_to_output_.swap(*frames_to_output);
312 }
313
danakj9c5cab52016-04-16 00:54:33314 int Call(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
Joshua Bell90829e32021-05-19 15:59:39315 CompletionOnceCallback callback) {
[email protected]ce9f7ffd2013-10-11 06:04:11316 DCHECK(frames->empty());
317 frames_passed_ = frames;
Joshua Bell90829e32021-05-19 15:59:39318 callback_ = std::move(callback);
[email protected]ce9f7ffd2013-10-11 06:04:11319 frames->swap(frames_to_output_);
320 return result_;
321 }
322
323 int result() const { return result_; }
Joshua Bell90829e32021-05-19 15:59:39324 CompletionOnceCallback& callback() { return callback_; }
danakj9c5cab52016-04-16 00:54:33325 std::vector<std::unique_ptr<WebSocketFrame>>* frames_passed() {
[email protected]ce9f7ffd2013-10-11 06:04:11326 return frames_passed_;
327 }
328
329 private:
330 int result_;
Joshua Bell90829e32021-05-19 15:59:39331 CompletionOnceCallback callback_;
danakj9c5cab52016-04-16 00:54:33332 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output_;
Keishi Hattori0e45c022021-11-27 09:25:52333 raw_ptr<std::vector<std::unique_ptr<WebSocketFrame>>> frames_passed_;
[email protected]ce9f7ffd2013-10-11 06:04:11334};
335
[email protected]ef735622013-10-30 14:28:18336// WriteFramesStub is a stub for WebSocketStream::WriteFrames.
[email protected]ce9f7ffd2013-10-11 06:04:11337// It returns |result_| and |frames_| to the caller and
338// saves |callback| parameter to |callback_|.
339class WriteFramesStub {
340 public:
[email protected]ef735622013-10-30 14:28:18341 explicit WriteFramesStub(WebSocketDeflatePredictorMock* predictor,
342 int result)
343 : result_(result), predictor_(predictor) {}
[email protected]ce9f7ffd2013-10-11 06:04:11344
danakj9c5cab52016-04-16 00:54:33345 int Call(std::vector<std::unique_ptr<WebSocketFrame>>* frames,
Joshua Bell90829e32021-05-19 15:59:39346 CompletionOnceCallback callback) {
yhirano592ff7f2015-12-07 08:45:19347 frames_.insert(frames_.end(), std::make_move_iterator(frames->begin()),
348 std::make_move_iterator(frames->end()));
349 frames->clear();
Joshua Bell90829e32021-05-19 15:59:39350 callback_ = std::move(callback);
[email protected]ef735622013-10-30 14:28:18351 predictor_->VerifySentFrames(frames_);
[email protected]ce9f7ffd2013-10-11 06:04:11352 return result_;
353 }
354
355 int result() const { return result_; }
Joshua Bell90829e32021-05-19 15:59:39356 CompletionOnceCallback& callback() { return callback_; }
danakj9c5cab52016-04-16 00:54:33357 std::vector<std::unique_ptr<WebSocketFrame>>* frames() { return &frames_; }
[email protected]ce9f7ffd2013-10-11 06:04:11358
359 private:
360 int result_;
Joshua Bell90829e32021-05-19 15:59:39361 CompletionOnceCallback callback_;
danakj9c5cab52016-04-16 00:54:33362 std::vector<std::unique_ptr<WebSocketFrame>> frames_;
Keishi Hattori0e45c022021-11-27 09:25:52363 raw_ptr<WebSocketDeflatePredictorMock> predictor_;
[email protected]ce9f7ffd2013-10-11 06:04:11364};
365
366TEST_F(WebSocketDeflateStreamTest, ReadFailedImmediately) {
danakj9c5cab52016-04-16 00:54:33367 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11368 {
369 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39370 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11371 .WillOnce(Return(ERR_FAILED));
372 }
Bence Békyf4f56e22018-07-17 02:00:05373 EXPECT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
robpercival214763f2016-07-01 23:27:01374 IsError(ERR_FAILED));
[email protected]ce9f7ffd2013-10-11 06:04:11375}
376
377TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameImmediately) {
danakj9c5cab52016-04-16 00:54:33378 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11379 AppendTo(&frames_to_output,
380 WebSocketFrameHeader::kOpCodeText,
381 kFinal,
382 "hello");
383 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33384 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11385
386 {
387 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39388 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11389 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
390 }
Bence Békyf4f56e22018-07-17 02:00:05391 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
392 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11393 ASSERT_EQ(1u, frames.size());
394 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
395 EXPECT_TRUE(frames[0]->header.final);
396 EXPECT_FALSE(frames[0]->header.reserved1);
397 EXPECT_EQ("hello", ToString(frames[0]));
398}
399
400TEST_F(WebSocketDeflateStreamTest, ReadUncompressedFrameAsync) {
401 ReadFramesStub stub(ERR_IO_PENDING);
danakj9c5cab52016-04-16 00:54:33402 std::vector<std::unique_ptr<WebSocketFrame>> frames;
Bence Békyf4f56e22018-07-17 02:00:05403 base::MockCallback<CompletionOnceCallback> mock_callback;
Anna Malova7c067d42020-03-04 17:09:13404 base::MockCallback<base::OnceClosure> checkpoint;
[email protected]ce9f7ffd2013-10-11 06:04:11405
406 {
407 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39408 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11409 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
jbromanc5b4bd262017-01-18 20:49:17410 EXPECT_CALL(checkpoint, Run());
411 EXPECT_CALL(mock_callback, Run(OK));
[email protected]ce9f7ffd2013-10-11 06:04:11412 }
jbromanc5b4bd262017-01-18 20:49:17413 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
robpercival214763f2016-07-01 23:27:01414 IsError(ERR_IO_PENDING));
[email protected]ce9f7ffd2013-10-11 06:04:11415 ASSERT_EQ(0u, frames.size());
416
jbromanc5b4bd262017-01-18 20:49:17417 checkpoint.Run();
[email protected]ce9f7ffd2013-10-11 06:04:11418
419 AppendTo(stub.frames_passed(),
420 WebSocketFrameHeader::kOpCodeText,
421 kFinal,
422 "hello");
Joshua Bell90829e32021-05-19 15:59:39423 std::move(stub.callback()).Run(OK);
[email protected]ce9f7ffd2013-10-11 06:04:11424 ASSERT_EQ(1u, frames.size());
425 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
426 EXPECT_TRUE(frames[0]->header.final);
427 EXPECT_FALSE(frames[0]->header.reserved1);
428 EXPECT_EQ("hello", ToString(frames[0]));
429}
430
431TEST_F(WebSocketDeflateStreamTest, ReadFailedAsync) {
432 ReadFramesStub stub(ERR_IO_PENDING);
danakj9c5cab52016-04-16 00:54:33433 std::vector<std::unique_ptr<WebSocketFrame>> frames;
Bence Békyf4f56e22018-07-17 02:00:05434 base::MockCallback<CompletionOnceCallback> mock_callback;
Anna Malova7c067d42020-03-04 17:09:13435 base::MockCallback<base::OnceClosure> checkpoint;
[email protected]ce9f7ffd2013-10-11 06:04:11436
437 {
438 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39439 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11440 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
jbromanc5b4bd262017-01-18 20:49:17441 EXPECT_CALL(checkpoint, Run());
442 EXPECT_CALL(mock_callback, Run(ERR_FAILED));
[email protected]ce9f7ffd2013-10-11 06:04:11443 }
jbromanc5b4bd262017-01-18 20:49:17444 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
robpercival214763f2016-07-01 23:27:01445 IsError(ERR_IO_PENDING));
[email protected]ce9f7ffd2013-10-11 06:04:11446 ASSERT_EQ(0u, frames.size());
447
jbromanc5b4bd262017-01-18 20:49:17448 checkpoint.Run();
[email protected]ce9f7ffd2013-10-11 06:04:11449
450 AppendTo(stub.frames_passed(),
451 WebSocketFrameHeader::kOpCodeText,
452 kFinal,
453 "hello");
Joshua Bell90829e32021-05-19 15:59:39454 std::move(stub.callback()).Run(ERR_FAILED);
[email protected]ce9f7ffd2013-10-11 06:04:11455 ASSERT_EQ(0u, frames.size());
456}
457
458TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameImmediately) {
danakj9c5cab52016-04-16 00:54:33459 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11460 AppendTo(&frames_to_output,
461 WebSocketFrameHeader::kOpCodeText,
462 kFinal | kReserved1,
463 std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
464 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33465 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11466 {
467 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39468 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11469 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
470 }
Bence Békyf4f56e22018-07-17 02:00:05471 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
472 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11473 ASSERT_EQ(1u, frames.size());
474 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
475 EXPECT_TRUE(frames[0]->header.final);
476 EXPECT_FALSE(frames[0]->header.reserved1);
477 EXPECT_EQ("Hello", ToString(frames[0]));
478}
479
480TEST_F(WebSocketDeflateStreamTest, ReadCompressedFrameAsync) {
481 ReadFramesStub stub(ERR_IO_PENDING);
jbromanc5b4bd262017-01-18 20:49:17482
Bence Békyf4f56e22018-07-17 02:00:05483 base::MockCallback<CompletionOnceCallback> mock_callback;
Anna Malova7c067d42020-03-04 17:09:13484 base::MockCallback<base::OnceClosure> checkpoint;
danakj9c5cab52016-04-16 00:54:33485 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11486 {
487 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39488 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11489 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
jbromanc5b4bd262017-01-18 20:49:17490 EXPECT_CALL(checkpoint, Run());
491 EXPECT_CALL(mock_callback, Run(OK));
[email protected]ce9f7ffd2013-10-11 06:04:11492 }
jbromanc5b4bd262017-01-18 20:49:17493 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
robpercival214763f2016-07-01 23:27:01494 IsError(ERR_IO_PENDING));
[email protected]ce9f7ffd2013-10-11 06:04:11495
jbromanc5b4bd262017-01-18 20:49:17496 checkpoint.Run();
[email protected]ce9f7ffd2013-10-11 06:04:11497
498 AppendTo(stub.frames_passed(),
499 WebSocketFrameHeader::kOpCodeText,
500 kFinal | kReserved1,
501 std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7));
Joshua Bell90829e32021-05-19 15:59:39502 std::move(stub.callback()).Run(OK);
[email protected]ce9f7ffd2013-10-11 06:04:11503
504 ASSERT_EQ(1u, frames.size());
505 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
506 EXPECT_TRUE(frames[0]->header.final);
507 EXPECT_FALSE(frames[0]->header.reserved1);
508 EXPECT_EQ("Hello", ToString(frames[0]));
509}
510
511TEST_F(WebSocketDeflateStreamTest,
512 ReadCompressedFrameFragmentImmediatelyButInflaterReturnsPending) {
danakj9c5cab52016-04-16 00:54:33513 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11514 const std::string data1("\xf2", 1);
515 const std::string data2("\x48\xcd\xc9\xc9\x07\x00", 6);
516 AppendTo(&frames_to_output,
517 WebSocketFrameHeader::kOpCodeText,
518 kReserved1,
519 data1);
520 ReadFramesStub stub1(OK, &frames_to_output), stub2(ERR_IO_PENDING);
Bence Békyf4f56e22018-07-17 02:00:05521 base::MockCallback<CompletionOnceCallback> mock_callback;
Anna Malova7c067d42020-03-04 17:09:13522 base::MockCallback<base::OnceClosure> checkpoint;
danakj9c5cab52016-04-16 00:54:33523 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11524
525 {
526 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39527 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11528 .WillOnce(Invoke(&stub1, &ReadFramesStub::Call))
529 .WillOnce(Invoke(&stub2, &ReadFramesStub::Call));
jbromanc5b4bd262017-01-18 20:49:17530 EXPECT_CALL(checkpoint, Run());
531 EXPECT_CALL(mock_callback, Run(OK));
[email protected]ce9f7ffd2013-10-11 06:04:11532 }
jbromanc5b4bd262017-01-18 20:49:17533 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
robpercival214763f2016-07-01 23:27:01534 IsError(ERR_IO_PENDING));
[email protected]ce9f7ffd2013-10-11 06:04:11535 ASSERT_EQ(0u, frames.size());
536
537 AppendTo(stub2.frames_passed(),
538 WebSocketFrameHeader::kOpCodeText,
539 kFinal,
540 data2);
541
jbromanc5b4bd262017-01-18 20:49:17542 checkpoint.Run();
Joshua Bell90829e32021-05-19 15:59:39543 std::move(stub2.callback()).Run(OK);
[email protected]ce9f7ffd2013-10-11 06:04:11544
545 ASSERT_EQ(1u, frames.size());
546 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
547 EXPECT_TRUE(frames[0]->header.final);
548 EXPECT_FALSE(frames[0]->header.reserved1);
549 EXPECT_EQ("Hello", ToString(frames[0]));
550}
551
552TEST_F(WebSocketDeflateStreamTest, ReadInvalidCompressedPayload) {
553 const std::string data("\xf2\x48\xcdINVALID", 10);
danakj9c5cab52016-04-16 00:54:33554 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11555 AppendTo(&frames_to_output,
556 WebSocketFrameHeader::kOpCodeText,
557 kFinal | kReserved1,
558 data);
559 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33560 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11561
562 {
563 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39564 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11565 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
566 }
567 ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
Bence Békyf4f56e22018-07-17 02:00:05568 deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()));
[email protected]ce9f7ffd2013-10-11 06:04:11569 ASSERT_EQ(0u, frames.size());
570}
571
572TEST_F(WebSocketDeflateStreamTest, MergeMultipleFramesInReadFrames) {
573 const std::string data1("\xf2\x48\xcd", 3);
574 const std::string data2("\xc9\xc9\x07\x00", 4);
danakj9c5cab52016-04-16 00:54:33575 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11576 AppendTo(&frames_to_output,
577 WebSocketFrameHeader::kOpCodeText,
578 kReserved1,
579 data1);
580 AppendTo(&frames_to_output,
581 WebSocketFrameHeader::kOpCodeContinuation,
582 kFinal,
583 data2);
584 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33585 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11586
587 {
588 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39589 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11590 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
591 }
Bence Békyf4f56e22018-07-17 02:00:05592 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
593 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11594 ASSERT_EQ(1u, frames.size());
595 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
596 EXPECT_TRUE(frames[0]->header.final);
597 EXPECT_FALSE(frames[0]->header.reserved1);
598 EXPECT_EQ("Hello", ToString(frames[0]));
599}
600
601TEST_F(WebSocketDeflateStreamTest, ReadUncompressedEmptyFrames) {
danakj9c5cab52016-04-16 00:54:33602 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11603 AppendTo(&frames_to_output,
604 WebSocketFrameHeader::kOpCodeText,
605 kNoFlag);
606 AppendTo(&frames_to_output,
607 WebSocketFrameHeader::kOpCodeContinuation,
608 kFinal);
609 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33610 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11611
612 {
613 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39614 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11615 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
616 }
Bence Békyf4f56e22018-07-17 02:00:05617 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
618 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11619 ASSERT_EQ(2u, frames.size());
620 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
621 EXPECT_FALSE(frames[0]->header.final);
622 EXPECT_FALSE(frames[0]->header.reserved1);
623 EXPECT_EQ("", ToString(frames[0]));
624 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
625 frames[1]->header.opcode);
626 EXPECT_TRUE(frames[1]->header.final);
627 EXPECT_FALSE(frames[1]->header.reserved1);
628 EXPECT_EQ("", ToString(frames[1]));
629}
630
631TEST_F(WebSocketDeflateStreamTest, ReadCompressedEmptyFrames) {
danakj9c5cab52016-04-16 00:54:33632 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11633 AppendTo(&frames_to_output,
634 WebSocketFrameHeader::kOpCodeText,
635 kReserved1,
636 std::string("\x02\x00", 1));
637 AppendTo(&frames_to_output,
638 WebSocketFrameHeader::kOpCodeContinuation,
639 kFinal);
640 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33641 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11642
643 {
644 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39645 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11646 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
647 }
Bence Békyf4f56e22018-07-17 02:00:05648 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
649 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11650 ASSERT_EQ(1u, frames.size());
651 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
652 EXPECT_TRUE(frames[0]->header.final);
653 EXPECT_FALSE(frames[0]->header.reserved1);
654 EXPECT_EQ("", ToString(frames[0]));
655}
656
657TEST_F(WebSocketDeflateStreamTest,
658 ReadCompressedFrameFollowedByEmptyFrame) {
659 const std::string data("\xf2\x48\xcd\xc9\xc9\x07\x00", 7);
danakj9c5cab52016-04-16 00:54:33660 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11661 AppendTo(&frames_to_output,
662 WebSocketFrameHeader::kOpCodeText,
663 kReserved1,
664 data);
665 AppendTo(&frames_to_output,
666 WebSocketFrameHeader::kOpCodeContinuation,
667 kFinal);
668 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33669 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11670
671 {
672 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39673 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11674 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
675 }
Bence Békyf4f56e22018-07-17 02:00:05676 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
677 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11678 ASSERT_EQ(1u, frames.size());
679 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
680 EXPECT_TRUE(frames[0]->header.final);
681 EXPECT_FALSE(frames[0]->header.reserved1);
682 EXPECT_EQ("Hello", ToString(frames[0]));
683}
684
685TEST_F(WebSocketDeflateStreamTest, ReadControlFrameBetweenDataFrames) {
686 const std::string data1("\xf2\x48\xcd", 3);
687 const std::string data2("\xc9\xc9\x07\x00", 4);
danakj9c5cab52016-04-16 00:54:33688 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11689 AppendTo(&frames_to_output,
690 WebSocketFrameHeader::kOpCodeText,
691 kReserved1,
692 data1);
693 AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodePing, kFinal);
694 AppendTo(&frames_to_output, WebSocketFrameHeader::kOpCodeText, kFinal, data2);
695 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33696 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11697
698 {
699 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39700 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11701 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
702 }
Bence Békyf4f56e22018-07-17 02:00:05703 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
704 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11705 ASSERT_EQ(2u, frames.size());
706 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames[0]->header.opcode);
707 EXPECT_TRUE(frames[0]->header.final);
708 EXPECT_FALSE(frames[0]->header.reserved1);
709 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
710 EXPECT_TRUE(frames[1]->header.final);
711 EXPECT_FALSE(frames[1]->header.reserved1);
712 EXPECT_EQ("Hello", ToString(frames[1]));
713}
714
715TEST_F(WebSocketDeflateStreamTest, SplitToMultipleFramesInReadFrames) {
716 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
717 deflater.Initialize(kWindowBits);
718 const size_t kSize = kChunkSize * 3;
719 const std::string original_data(kSize, 'a');
720 deflater.AddBytes(original_data.data(), original_data.size());
721 deflater.Finish();
722
danakj9c5cab52016-04-16 00:54:33723 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11724 AppendTo(&frames_to_output,
725 WebSocketFrameHeader::kOpCodeBinary,
726 kFinal | kReserved1,
727 ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
728
729 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33730 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11731 {
732 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39733 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11734 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
735 }
736
Bence Békyf4f56e22018-07-17 02:00:05737 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
738 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11739 ASSERT_EQ(3u, frames.size());
740 EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
741 EXPECT_FALSE(frames[0]->header.final);
742 EXPECT_FALSE(frames[0]->header.reserved1);
743 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
744 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
745 frames[1]->header.opcode);
746 EXPECT_FALSE(frames[1]->header.final);
747 EXPECT_FALSE(frames[1]->header.reserved1);
748 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[1]->header.payload_length));
749 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
750 frames[2]->header.opcode);
751 EXPECT_TRUE(frames[2]->header.final);
752 EXPECT_FALSE(frames[2]->header.reserved1);
753 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[2]->header.payload_length));
754 EXPECT_EQ(original_data,
755 ToString(frames[0]) + ToString(frames[1]) + ToString(frames[2]));
756}
757
[email protected]d0f628f2014-04-16 17:09:19758TEST_F(WebSocketDeflateStreamTest, InflaterInternalDataCanBeEmpty) {
759 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
760 deflater.Initialize(kWindowBits);
761 const std::string original_data(kChunkSize, 'a');
762 deflater.AddBytes(original_data.data(), original_data.size());
763 deflater.Finish();
764
danakj9c5cab52016-04-16 00:54:33765 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]d0f628f2014-04-16 17:09:19766 AppendTo(&frames_to_output,
767 WebSocketFrameHeader::kOpCodeBinary,
768 kReserved1,
769 ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
770 AppendTo(&frames_to_output,
771 WebSocketFrameHeader::kOpCodeBinary,
772 kFinal,
773 "");
774
775 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33776 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]d0f628f2014-04-16 17:09:19777 {
778 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39779 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]d0f628f2014-04-16 17:09:19780 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
781 }
782
Bence Békyf4f56e22018-07-17 02:00:05783 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
784 IsOk());
[email protected]d0f628f2014-04-16 17:09:19785 ASSERT_EQ(2u, frames.size());
786 EXPECT_EQ(WebSocketFrameHeader::kOpCodeBinary, frames[0]->header.opcode);
787 EXPECT_FALSE(frames[0]->header.final);
788 EXPECT_FALSE(frames[0]->header.reserved1);
789 EXPECT_EQ(kChunkSize, static_cast<size_t>(frames[0]->header.payload_length));
790
791 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
792 frames[1]->header.opcode);
793 EXPECT_TRUE(frames[1]->header.final);
794 EXPECT_FALSE(frames[1]->header.reserved1);
795 EXPECT_EQ(0u, static_cast<size_t>(frames[1]->header.payload_length));
796 EXPECT_EQ(original_data, ToString(frames[0]) + ToString(frames[1]));
797}
798
[email protected]ce9f7ffd2013-10-11 06:04:11799TEST_F(WebSocketDeflateStreamTest,
800 Reserved1TurnsOnDuringReadingCompressedContinuationFrame) {
801 const std::string data1("\xf2\x48\xcd", 3);
802 const std::string data2("\xc9\xc9\x07\x00", 4);
danakj9c5cab52016-04-16 00:54:33803 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11804 AppendTo(&frames_to_output,
805 WebSocketFrameHeader::kOpCodeText,
806 kReserved1,
807 data1);
808 AppendTo(&frames_to_output,
809 WebSocketFrameHeader::kOpCodeContinuation,
810 kFinal | kReserved1,
811 data2);
812 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33813 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11814
815 {
816 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39817 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11818 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
819 }
820 ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
Bence Békyf4f56e22018-07-17 02:00:05821 deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()));
[email protected]ce9f7ffd2013-10-11 06:04:11822}
823
824TEST_F(WebSocketDeflateStreamTest,
825 Reserved1TurnsOnDuringReadingUncompressedContinuationFrame) {
danakj9c5cab52016-04-16 00:54:33826 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11827 AppendTo(&frames_to_output,
828 WebSocketFrameHeader::kOpCodeText,
829 kNoFlag,
830 "hello");
831 AppendTo(&frames_to_output,
832 WebSocketFrameHeader::kOpCodeContinuation,
833 kFinal | kReserved1,
834 "world");
835 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33836 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11837
838 {
839 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39840 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11841 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
842 }
843 ASSERT_EQ(ERR_WS_PROTOCOL_ERROR,
Bence Békyf4f56e22018-07-17 02:00:05844 deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()));
[email protected]ce9f7ffd2013-10-11 06:04:11845}
846
847TEST_F(WebSocketDeflateStreamTest, ReadCompressedMessages) {
danakj9c5cab52016-04-16 00:54:33848 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11849 AppendTo(&frames_to_output,
850 WebSocketFrameHeader::kOpCodeText,
851 kFinal | kReserved1,
852 std::string(
853 "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x31\x04\x00", 13));
854 AppendTo(&frames_to_output,
855 WebSocketFrameHeader::kOpCodeText,
856 kFinal | kReserved1,
857 std::string("\x4a\x86\x33\x8d\x00\x00", 6));
858 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33859 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11860
861 {
862 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39863 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11864 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
865 }
Bence Békyf4f56e22018-07-17 02:00:05866 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
867 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11868 ASSERT_EQ(2u, frames.size());
869 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
870 EXPECT_TRUE(frames[0]->header.final);
871 EXPECT_FALSE(frames[0]->header.reserved1);
872 EXPECT_EQ("compressed1", ToString(frames[0]));
873 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
874 EXPECT_TRUE(frames[1]->header.final);
875 EXPECT_FALSE(frames[1]->header.reserved1);
876 EXPECT_EQ("compressed2", ToString(frames[1]));
877}
878
879TEST_F(WebSocketDeflateStreamTest, ReadUncompressedMessages) {
danakj9c5cab52016-04-16 00:54:33880 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11881 AppendTo(&frames_to_output,
882 WebSocketFrameHeader::kOpCodeText,
883 kFinal,
884 "uncompressed1");
885 AppendTo(&frames_to_output,
886 WebSocketFrameHeader::kOpCodeText,
887 kFinal,
888 "uncompressed2");
889 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33890 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11891
892 {
893 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39894 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11895 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
896 }
Bence Békyf4f56e22018-07-17 02:00:05897 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
898 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11899 ASSERT_EQ(2u, frames.size());
900 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
901 EXPECT_TRUE(frames[0]->header.final);
902 EXPECT_FALSE(frames[0]->header.reserved1);
903 EXPECT_EQ("uncompressed1", ToString(frames[0]));
904 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
905 EXPECT_TRUE(frames[1]->header.final);
906 EXPECT_FALSE(frames[1]->header.reserved1);
907 EXPECT_EQ("uncompressed2", ToString(frames[1]));
908}
909
910TEST_F(WebSocketDeflateStreamTest,
911 ReadCompressedMessageThenUncompressedMessage) {
danakj9c5cab52016-04-16 00:54:33912 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11913 AppendTo(&frames_to_output,
914 WebSocketFrameHeader::kOpCodeText,
915 kFinal | kReserved1,
916 std::string(
917 "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
918 AppendTo(&frames_to_output,
919 WebSocketFrameHeader::kOpCodeText,
920 kFinal,
921 "uncompressed");
922 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33923 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11924
925 {
926 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39927 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11928 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
929 }
Bence Békyf4f56e22018-07-17 02:00:05930 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
931 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11932 ASSERT_EQ(2u, frames.size());
933 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
934 EXPECT_TRUE(frames[0]->header.final);
935 EXPECT_FALSE(frames[0]->header.reserved1);
936 EXPECT_EQ("compressed", ToString(frames[0]));
937 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
938 EXPECT_TRUE(frames[1]->header.final);
939 EXPECT_FALSE(frames[1]->header.reserved1);
940 EXPECT_EQ("uncompressed", ToString(frames[1]));
941}
942
943TEST_F(WebSocketDeflateStreamTest,
944 ReadUncompressedMessageThenCompressedMessage) {
danakj9c5cab52016-04-16 00:54:33945 std::vector<std::unique_ptr<WebSocketFrame>> frames_to_output;
[email protected]ce9f7ffd2013-10-11 06:04:11946 AppendTo(&frames_to_output,
947 WebSocketFrameHeader::kOpCodeText,
948 kFinal,
949 "uncompressed");
950 AppendTo(&frames_to_output,
951 WebSocketFrameHeader::kOpCodeText,
952 kFinal | kReserved1,
953 std::string(
954 "\x4a\xce\xcf\x2d\x28\x4a\x2d\x2e\x4e\x4d\x01\x00", 12));
955 ReadFramesStub stub(OK, &frames_to_output);
danakj9c5cab52016-04-16 00:54:33956 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:11957
958 {
959 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39960 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:11961 .WillOnce(Invoke(&stub, &ReadFramesStub::Call));
962 }
Bence Békyf4f56e22018-07-17 02:00:05963 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, CompletionOnceCallback()),
964 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:11965 ASSERT_EQ(2u, frames.size());
966 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
967 EXPECT_TRUE(frames[0]->header.final);
968 EXPECT_FALSE(frames[0]->header.reserved1);
969 EXPECT_EQ("uncompressed", ToString(frames[0]));
970 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[1]->header.opcode);
971 EXPECT_TRUE(frames[1]->header.final);
972 EXPECT_FALSE(frames[1]->header.reserved1);
973 EXPECT_EQ("compressed", ToString(frames[1]));
974}
975
[email protected]658d2e82014-02-21 05:09:31976// This is a regression test for crbug.com/343506.
977TEST_F(WebSocketDeflateStreamTest, ReadEmptyAsyncFrame) {
danakj9c5cab52016-04-16 00:54:33978 std::vector<std::unique_ptr<ReadFramesStub>> stub_vector;
Bence Béky8f9d7d3952017-10-09 19:58:04979 stub_vector.push_back(std::make_unique<ReadFramesStub>(ERR_IO_PENDING));
980 stub_vector.push_back(std::make_unique<ReadFramesStub>(ERR_IO_PENDING));
Bence Békyf4f56e22018-07-17 02:00:05981 base::MockCallback<CompletionOnceCallback> mock_callback;
danakj9c5cab52016-04-16 00:54:33982 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]658d2e82014-02-21 05:09:31983
984 {
985 InSequence s;
Joshua Bell90829e32021-05-19 15:59:39986 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
yhirano592ff7f2015-12-07 08:45:19987 .WillOnce(Invoke(stub_vector[0].get(), &ReadFramesStub::Call));
[email protected]658d2e82014-02-21 05:09:31988
Joshua Bell90829e32021-05-19 15:59:39989 EXPECT_CALL(*mock_stream_, ReadFrames(&frames, _))
yhirano592ff7f2015-12-07 08:45:19990 .WillOnce(Invoke(stub_vector[1].get(), &ReadFramesStub::Call));
[email protected]658d2e82014-02-21 05:09:31991
jbromanc5b4bd262017-01-18 20:49:17992 EXPECT_CALL(mock_callback, Run(OK));
[email protected]658d2e82014-02-21 05:09:31993 }
994
jbromanc5b4bd262017-01-18 20:49:17995 ASSERT_THAT(deflate_stream_->ReadFrames(&frames, mock_callback.Get()),
robpercival214763f2016-07-01 23:27:01996 IsError(ERR_IO_PENDING));
[email protected]658d2e82014-02-21 05:09:31997 AppendTo(stub_vector[0]->frames_passed(),
998 WebSocketFrameHeader::kOpCodeText,
999 kReserved1,
1000 std::string());
Joshua Bell90829e32021-05-19 15:59:391001 std::move(stub_vector[0]->callback()).Run(OK);
[email protected]658d2e82014-02-21 05:09:311002 AppendTo(stub_vector[1]->frames_passed(),
1003 WebSocketFrameHeader::kOpCodeContinuation,
1004 kFinal,
1005 std::string("\x02\x00"));
Joshua Bell90829e32021-05-19 15:59:391006 std::move(stub_vector[1]->callback()).Run(OK);
[email protected]658d2e82014-02-21 05:09:311007 ASSERT_EQ(1u, frames.size());
1008 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames[0]->header.opcode);
1009 EXPECT_EQ("", ToString(frames[0]));
1010}
1011
[email protected]ce9f7ffd2013-10-11 06:04:111012TEST_F(WebSocketDeflateStreamTest, WriteEmpty) {
danakj9c5cab52016-04-16 00:54:331013 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:111014 {
1015 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391016 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _)).Times(0);
[email protected]ce9f7ffd2013-10-11 06:04:111017 }
Bence Békyf4f56e22018-07-17 02:00:051018 EXPECT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1019 IsOk());
[email protected]ce9f7ffd2013-10-11 06:04:111020}
1021
1022TEST_F(WebSocketDeflateStreamTest, WriteFailedImmediately) {
danakj9c5cab52016-04-16 00:54:331023 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:111024 {
1025 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391026 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:111027 .WillOnce(Return(ERR_FAILED));
1028 }
1029
1030 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "hello");
[email protected]ef735622013-10-30 14:28:181031 predictor_->AddFramesToBeInput(frames);
Bence Békyf4f56e22018-07-17 02:00:051032 EXPECT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
robpercival214763f2016-07-01 23:27:011033 IsError(ERR_FAILED));
[email protected]ef735622013-10-30 14:28:181034 predictor_->Clear();
[email protected]ce9f7ffd2013-10-11 06:04:111035}
1036
1037TEST_F(WebSocketDeflateStreamTest, WriteFrameImmediately) {
danakj9c5cab52016-04-16 00:54:331038 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ef735622013-10-30 14:28:181039 WriteFramesStub stub(predictor_, OK);
[email protected]ce9f7ffd2013-10-11 06:04:111040 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
[email protected]ef735622013-10-30 14:28:181041 predictor_->AddFramesToBeInput(frames);
[email protected]ce9f7ffd2013-10-11 06:04:111042 {
1043 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391044 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
[email protected]ce9f7ffd2013-10-11 06:04:111045 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1046 }
Bence Békyf4f56e22018-07-17 02:00:051047 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1048 IsOk());
danakj9c5cab52016-04-16 00:54:331049 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1050 *stub.frames();
[email protected]ce9f7ffd2013-10-11 06:04:111051 ASSERT_EQ(1u, frames_passed.size());
1052 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1053 EXPECT_TRUE(frames_passed[0]->header.final);
1054 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1055 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1056 ToString(frames_passed[0]));
1057}
1058
1059TEST_F(WebSocketDeflateStreamTest, WriteFrameAsync) {
[email protected]ef735622013-10-30 14:28:181060 WriteFramesStub stub(predictor_, ERR_IO_PENDING);
Bence Békyf4f56e22018-07-17 02:00:051061 base::MockCallback<CompletionOnceCallback> mock_callback;
Anna Malova7c067d42020-03-04 17:09:131062 base::MockCallback<base::OnceClosure> checkpoint;
danakj9c5cab52016-04-16 00:54:331063 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:111064 {
1065 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391066 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:111067 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
jbromanc5b4bd262017-01-18 20:49:171068 EXPECT_CALL(checkpoint, Run());
1069 EXPECT_CALL(mock_callback, Run(OK));
[email protected]ce9f7ffd2013-10-11 06:04:111070 }
1071 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
[email protected]ef735622013-10-30 14:28:181072 predictor_->AddFramesToBeInput(frames);
jbromanc5b4bd262017-01-18 20:49:171073 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, mock_callback.Get()),
robpercival214763f2016-07-01 23:27:011074 IsError(ERR_IO_PENDING));
[email protected]ce9f7ffd2013-10-11 06:04:111075
jbromanc5b4bd262017-01-18 20:49:171076 checkpoint.Run();
Joshua Bell90829e32021-05-19 15:59:391077 std::move(stub.callback()).Run(OK);
[email protected]ce9f7ffd2013-10-11 06:04:111078
danakj9c5cab52016-04-16 00:54:331079 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1080 *stub.frames();
[email protected]ce9f7ffd2013-10-11 06:04:111081 ASSERT_EQ(1u, frames_passed.size());
1082 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1083 EXPECT_TRUE(frames_passed[0]->header.final);
1084 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1085 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1086 ToString(frames_passed[0]));
1087}
1088
1089TEST_F(WebSocketDeflateStreamTest, WriteControlFrameBetweenDataFrames) {
danakj9c5cab52016-04-16 00:54:331090 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:111091 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "Hel");
1092 AppendTo(&frames, WebSocketFrameHeader::kOpCodePing, kFinal);
1093 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "lo");
[email protected]ef735622013-10-30 14:28:181094 predictor_->AddFramesToBeInput(frames);
1095 WriteFramesStub stub(predictor_, OK);
[email protected]ce9f7ffd2013-10-11 06:04:111096
1097 {
1098 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391099 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:111100 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1101 }
Bence Békyf4f56e22018-07-17 02:00:051102 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1103 IsOk());
danakj9c5cab52016-04-16 00:54:331104 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1105 *stub.frames();
[email protected]ce9f7ffd2013-10-11 06:04:111106 ASSERT_EQ(2u, frames_passed.size());
1107 EXPECT_EQ(WebSocketFrameHeader::kOpCodePing, frames_passed[0]->header.opcode);
1108 EXPECT_TRUE(frames_passed[0]->header.final);
1109 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1110 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1111 EXPECT_TRUE(frames_passed[1]->header.final);
1112 EXPECT_TRUE(frames_passed[1]->header.reserved1);
1113 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1114 ToString(frames_passed[1]));
1115}
1116
1117TEST_F(WebSocketDeflateStreamTest, WriteEmptyMessage) {
danakj9c5cab52016-04-16 00:54:331118 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:111119 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal);
[email protected]ef735622013-10-30 14:28:181120 predictor_->AddFramesToBeInput(frames);
1121 WriteFramesStub stub(predictor_, OK);
[email protected]ce9f7ffd2013-10-11 06:04:111122
1123 {
1124 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391125 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]ce9f7ffd2013-10-11 06:04:111126 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1127 }
Bence Békyf4f56e22018-07-17 02:00:051128 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1129 IsOk());
danakj9c5cab52016-04-16 00:54:331130 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1131 *stub.frames();
[email protected]ce9f7ffd2013-10-11 06:04:111132 ASSERT_EQ(1u, frames_passed.size());
1133 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1134 EXPECT_TRUE(frames_passed[0]->header.final);
1135 EXPECT_TRUE(frames_passed[0]->header.reserved1);
[email protected]5316ba02014-01-24 15:31:341136 EXPECT_EQ(std::string("\x00", 1), ToString(frames_passed[0]));
[email protected]ce9f7ffd2013-10-11 06:04:111137}
1138
[email protected]ef735622013-10-30 14:28:181139TEST_F(WebSocketDeflateStreamTest, WriteUncompressedMessage) {
danakj9c5cab52016-04-16 00:54:331140 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ef735622013-10-30 14:28:181141 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAA");
1142 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AAA");
1143 predictor_->AddFramesToBeInput(frames);
1144 WriteFramesStub stub(predictor_, OK);
[email protected]ef735622013-10-30 14:28:181145
1146 predictor_->set_result(WebSocketDeflatePredictor::DO_NOT_DEFLATE);
1147
1148 {
1149 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391150 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]ef735622013-10-30 14:28:181151 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1152 }
Bence Békyf4f56e22018-07-17 02:00:051153 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1154 IsOk());
danakj9c5cab52016-04-16 00:54:331155 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1156 *stub.frames();
[email protected]ef735622013-10-30 14:28:181157 ASSERT_EQ(2u, frames_passed.size());
1158 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1159 EXPECT_FALSE(frames_passed[0]->header.final);
1160 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1161 EXPECT_EQ("AAAA", ToString(frames_passed[0]));
1162 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1163 frames_passed[1]->header.opcode);
1164 EXPECT_TRUE(frames_passed[1]->header.final);
1165 EXPECT_FALSE(frames_passed[1]->header.reserved1);
1166 EXPECT_EQ("AAA", ToString(frames_passed[1]));
1167}
1168
[email protected]ce9f7ffd2013-10-11 06:04:111169TEST_F(WebSocketDeflateStreamTest, LargeDeflatedFramesShouldBeSplit) {
1170 WebSocketDeflater deflater(WebSocketDeflater::TAKE_OVER_CONTEXT);
1171 LinearCongruentialGenerator lcg(133);
[email protected]ef735622013-10-30 14:28:181172 WriteFramesStub stub(predictor_, OK);
[email protected]ce9f7ffd2013-10-11 06:04:111173 const size_t size = 1024;
1174
1175 {
1176 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391177 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
[email protected]ce9f7ffd2013-10-11 06:04:111178 .WillRepeatedly(Invoke(&stub, &WriteFramesStub::Call));
1179 }
danakj9c5cab52016-04-16 00:54:331180 std::vector<std::unique_ptr<WebSocketFrame>> total_compressed_frames;
Yutaka Hirano76aacb202019-09-05 16:36:561181 std::vector<std::string> buffers;
[email protected]ce9f7ffd2013-10-11 06:04:111182
1183 deflater.Initialize(kWindowBits);
1184 while (true) {
1185 bool is_final = (total_compressed_frames.size() >= 2);
danakj9c5cab52016-04-16 00:54:331186 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ce9f7ffd2013-10-11 06:04:111187 std::string data;
1188 for (size_t i = 0; i < size; ++i)
1189 data += static_cast<char>(lcg.Generate());
1190 deflater.AddBytes(data.data(), data.size());
1191 FrameFlag flag = is_final ? kFinal : kNoFlag;
1192 AppendTo(&frames, WebSocketFrameHeader::kOpCodeBinary, flag, data);
[email protected]ef735622013-10-30 14:28:181193 predictor_->AddFramesToBeInput(frames);
Bence Békyf4f56e22018-07-17 02:00:051194 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1195 IsOk());
Yutaka Hirano76aacb202019-09-05 16:36:561196 for (auto& frame : *stub.frames()) {
Tsuyoshi Horoebc507882022-06-30 11:16:451197 buffers.emplace_back(frame->payload, frame->header.payload_length);
Yoichi Osato05cd3642019-09-09 18:13:081198 frame->payload = (buffers.end() - 1)->data();
Yutaka Hirano76aacb202019-09-05 16:36:561199 }
yhirano592ff7f2015-12-07 08:45:191200 total_compressed_frames.insert(
1201 total_compressed_frames.end(),
1202 std::make_move_iterator(stub.frames()->begin()),
1203 std::make_move_iterator(stub.frames()->end()));
1204 stub.frames()->clear();
[email protected]ce9f7ffd2013-10-11 06:04:111205 if (is_final)
1206 break;
1207 }
1208 deflater.Finish();
1209 std::string total_deflated;
1210 for (size_t i = 0; i < total_compressed_frames.size(); ++i) {
yhirano592ff7f2015-12-07 08:45:191211 WebSocketFrame* frame = total_compressed_frames[i].get();
[email protected]ce9f7ffd2013-10-11 06:04:111212 const WebSocketFrameHeader& header = frame->header;
1213 if (i > 0) {
1214 EXPECT_EQ(header.kOpCodeContinuation, header.opcode);
1215 EXPECT_FALSE(header.reserved1);
1216 } else {
1217 EXPECT_EQ(header.kOpCodeBinary, header.opcode);
1218 EXPECT_TRUE(header.reserved1);
1219 }
1220 const bool is_final_frame = (i + 1 == total_compressed_frames.size());
1221 EXPECT_EQ(is_final_frame, header.final);
1222 if (!is_final_frame)
1223 EXPECT_GT(header.payload_length, 0ul);
1224 total_deflated += ToString(frame);
1225 }
1226 EXPECT_EQ(total_deflated,
1227 ToString(deflater.GetOutput(deflater.CurrentOutputSize())));
1228}
1229
[email protected]77c55ca32013-10-24 12:07:361230TEST_F(WebSocketDeflateStreamTest, WriteMultipleMessages) {
danakj9c5cab52016-04-16 00:54:331231 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]77c55ca32013-10-24 12:07:361232 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1233 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
[email protected]ef735622013-10-30 14:28:181234 predictor_->AddFramesToBeInput(frames);
1235 WriteFramesStub stub(predictor_, OK);
[email protected]77c55ca32013-10-24 12:07:361236
1237 {
1238 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391239 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]77c55ca32013-10-24 12:07:361240 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1241 }
Bence Békyf4f56e22018-07-17 02:00:051242 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1243 IsOk());
danakj9c5cab52016-04-16 00:54:331244 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1245 *stub.frames();
[email protected]77c55ca32013-10-24 12:07:361246 ASSERT_EQ(2u, frames_passed.size());
1247 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1248 EXPECT_TRUE(frames_passed[0]->header.final);
1249 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1250 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1251 ToString(frames_passed[0]));
1252 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1253 EXPECT_TRUE(frames_passed[1]->header.final);
1254 EXPECT_TRUE(frames_passed[1]->header.reserved1);
1255 EXPECT_EQ(std::string("\xf2\x00\x11\x00\x00", 5), ToString(frames_passed[1]));
1256}
1257
1258TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1259 WriteMultipleMessages) {
danakj9c5cab52016-04-16 00:54:331260 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]77c55ca32013-10-24 12:07:361261 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
1262 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kFinal, "Hello");
[email protected]ef735622013-10-30 14:28:181263 predictor_->AddFramesToBeInput(frames);
1264 WriteFramesStub stub(predictor_, OK);
[email protected]77c55ca32013-10-24 12:07:361265
1266 {
1267 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391268 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]77c55ca32013-10-24 12:07:361269 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1270 }
Bence Békyf4f56e22018-07-17 02:00:051271 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1272 IsOk());
danakj9c5cab52016-04-16 00:54:331273 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1274 *stub.frames();
[email protected]77c55ca32013-10-24 12:07:361275 ASSERT_EQ(2u, frames_passed.size());
1276 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1277 EXPECT_TRUE(frames_passed[0]->header.final);
1278 EXPECT_TRUE(frames_passed[0]->header.reserved1);
1279 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1280 ToString(frames_passed[0]));
1281 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[1]->header.opcode);
1282 EXPECT_TRUE(frames_passed[1]->header.final);
1283 EXPECT_TRUE(frames_passed[1]->header.reserved1);
1284 EXPECT_EQ(std::string("\xf2\x48\xcd\xc9\xc9\x07\x00", 7),
1285 ToString(frames_passed[1]));
1286}
1287
[email protected]ef735622013-10-30 14:28:181288// In order to check the stream works correctly for multiple
1289// "PossiblyCompressedMessage"s, we test various messages at one test case.
1290TEST_F(WebSocketDeflateStreamWithDoNotTakeOverContextTest,
1291 WritePossiblyCompressMessages) {
danakj9c5cab52016-04-16 00:54:331292 std::vector<std::unique_ptr<WebSocketFrame>> frames;
[email protected]ef735622013-10-30 14:28:181293 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "He");
1294 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "llo");
1295 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "AAAAAAAAAA");
1296 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "AA");
1297 AppendTo(&frames, WebSocketFrameHeader::kOpCodeText, kNoFlag, "XX");
1298 AppendTo(&frames, WebSocketFrameHeader::kOpCodeContinuation, kFinal, "YY");
1299 predictor_->AddFramesToBeInput(frames);
1300 WriteFramesStub stub(predictor_, OK);
[email protected]ef735622013-10-30 14:28:181301 predictor_->set_result(WebSocketDeflatePredictor::TRY_DEFLATE);
1302
1303 {
1304 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391305 EXPECT_CALL(*mock_stream_, WriteFrames(&frames, _))
[email protected]ef735622013-10-30 14:28:181306 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1307 }
Bence Békyf4f56e22018-07-17 02:00:051308 ASSERT_THAT(deflate_stream_->WriteFrames(&frames, CompletionOnceCallback()),
1309 IsOk());
danakj9c5cab52016-04-16 00:54:331310 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1311 *stub.frames();
[email protected]ef735622013-10-30 14:28:181312 ASSERT_EQ(5u, frames_passed.size());
1313
1314 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[0]->header.opcode);
1315 EXPECT_FALSE(frames_passed[0]->header.final);
1316 EXPECT_FALSE(frames_passed[0]->header.reserved1);
1317 EXPECT_EQ("He", ToString(frames_passed[0]));
1318 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1319 frames_passed[1]->header.opcode);
1320 EXPECT_TRUE(frames_passed[1]->header.final);
1321 EXPECT_FALSE(frames_passed[1]->header.reserved1);
1322 EXPECT_EQ("llo", ToString(frames_passed[1]));
1323
1324 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[2]->header.opcode);
1325 EXPECT_TRUE(frames_passed[2]->header.final);
1326 EXPECT_TRUE(frames_passed[2]->header.reserved1);
1327 EXPECT_EQ(std::string("\x72\x74\x44\x00\x00\x00", 6),
1328 ToString(frames_passed[2]));
1329
1330 EXPECT_EQ(WebSocketFrameHeader::kOpCodeText, frames_passed[3]->header.opcode);
1331 EXPECT_FALSE(frames_passed[3]->header.final);
1332 EXPECT_FALSE(frames_passed[3]->header.reserved1);
1333 EXPECT_EQ("XX", ToString(frames_passed[3]));
1334 EXPECT_EQ(WebSocketFrameHeader::kOpCodeContinuation,
1335 frames_passed[4]->header.opcode);
1336 EXPECT_TRUE(frames_passed[4]->header.final);
1337 EXPECT_FALSE(frames_passed[4]->header.reserved1);
1338 EXPECT_EQ("YY", ToString(frames_passed[4]));
1339}
1340
[email protected]4a2ad812c2014-01-21 09:59:431341// This is based on the similar test from websocket_deflater_test.cc
1342TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits8) {
1343 SetUpWithWindowBits(8);
[email protected]4a2ad812c2014-01-21 09:59:431344 AddCompressibleFrameString();
1345 WriteFramesStub stub(predictor_, OK);
1346 {
1347 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391348 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
[email protected]4a2ad812c2014-01-21 09:59:431349 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1350 }
Bence Békyf4f56e22018-07-17 02:00:051351 ASSERT_THAT(deflate_stream_->WriteFrames(&frames_, CompletionOnceCallback()),
1352 IsOk());
danakj9c5cab52016-04-16 00:54:331353 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1354 *stub.frames();
[email protected]4a2ad812c2014-01-21 09:59:431355 ASSERT_EQ(1u, frames_passed.size());
1356 EXPECT_EQ(std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x39\xa3"
1357 "(?7\xb3\x34\x17\x00", 21),
1358 ToString(frames_passed[0]));
1359}
1360
1361// The same input with window_bits=10 returns smaller output.
1362TEST_F(WebSocketDeflateStreamWithClientWindowBitsTest, WindowBits10) {
1363 SetUpWithWindowBits(10);
[email protected]4a2ad812c2014-01-21 09:59:431364 AddCompressibleFrameString();
1365 WriteFramesStub stub(predictor_, OK);
1366 {
1367 InSequence s;
Joshua Bell90829e32021-05-19 15:59:391368 EXPECT_CALL(*mock_stream_, WriteFrames(_, _))
[email protected]4a2ad812c2014-01-21 09:59:431369 .WillOnce(Invoke(&stub, &WriteFramesStub::Call));
1370 }
Bence Békyf4f56e22018-07-17 02:00:051371 ASSERT_THAT(deflate_stream_->WriteFrames(&frames_, CompletionOnceCallback()),
1372 IsOk());
danakj9c5cab52016-04-16 00:54:331373 const std::vector<std::unique_ptr<WebSocketFrame>>& frames_passed =
1374 *stub.frames();
[email protected]4a2ad812c2014-01-21 09:59:431375 ASSERT_EQ(1u, frames_passed.size());
1376 EXPECT_EQ(
1377 std::string("r\xce(\xca\xcf\xcd,\xcdM\x1c\xe1\xc0\x19\x1a\x0e\0\0", 17),
1378 ToString(frames_passed[0]));
1379}
1380
[email protected]ce9f7ffd2013-10-11 06:04:111381} // namespace
1382
1383} // namespace net