blob: e6ac53f5fc1bc2d10b4cf49e8d424c6e889df6ed [file] [log] [blame]
xunjieli11834f02015-12-22 04:27:081// Copyright 2015 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/http/bidirectional_stream.h"
6
danakj1fd259a02016-04-16 03:17:097#include <memory>
diannahu9904e272017-02-03 14:40:088#include <string>
bnc086b39e12016-06-24 13:05:269#include <utility>
diannahu9904e272017-02-03 14:40:0810#include <vector>
danakj1fd259a02016-04-16 03:17:0911
Ryan Sleevib8d7ea02018-05-07 20:01:0112#include "base/containers/span.h"
danakj1fd259a02016-04-16 03:17:0913#include "base/memory/ptr_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
xunjieli11834f02015-12-22 04:27:0815#include "base/run_loop.h"
xunjieli11834f02015-12-22 04:27:0816#include "base/strings/string_number_conversions.h"
xunjieli11834f02015-12-22 04:27:0817#include "base/time/time.h"
18#include "base/timer/mock_timer.h"
Sebastien Marchandefda77e532019-01-25 22:53:5219#include "base/timer/timer.h"
Paul Jensen76bfe082018-02-23 03:36:0520#include "build/build_config.h"
Bence Békya4a50932018-08-10 13:39:4121#include "net/base/completion_once_callback.h"
xunjieli369d0922016-09-23 18:45:0622#include "net/base/load_timing_info.h"
23#include "net/base/load_timing_info_test_util.h"
xunjieli11834f02015-12-22 04:27:0824#include "net/base/net_errors.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2325#include "net/dns/public/secure_dns_policy.h"
xunjieli11834f02015-12-22 04:27:0826#include "net/http/bidirectional_stream_request_info.h"
27#include "net/http/http_network_session.h"
28#include "net/http/http_response_headers.h"
xunjielib3a648e2016-03-22 03:39:5129#include "net/http/http_server_properties.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2630#include "net/log/net_log.h"
mikecironef22f9812016-10-04 03:40:1931#include "net/log/net_log_capture_mode.h"
mikecirone8b85c432016-09-08 19:11:0032#include "net/log/net_log_event_type.h"
33#include "net/log/net_log_source_type.h"
xunjielibe07785e2016-04-14 21:15:2934#include "net/log/test_net_log.h"
35#include "net/log/test_net_log_util.h"
Paul Jensena457017a2018-01-19 23:52:0436#include "net/socket/socket_tag.h"
xunjieli11834f02015-12-22 04:27:0837#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5838#include "net/spdy/spdy_session.h"
39#include "net/spdy/spdy_test_util_common.h"
Helen Li43e3bee2018-03-21 16:57:1140#include "net/ssl/ssl_cert_request_info.h"
xunjieli11834f02015-12-22 04:27:0841#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0142#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4343#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4044#include "net/test/test_with_task_environment.h"
xunjieli11834f02015-12-22 04:27:0845#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0146#include "testing/gmock/include/gmock/gmock.h"
xunjieli11834f02015-12-22 04:27:0847#include "testing/gtest/include/gtest/gtest.h"
48
robpercival214763f2016-07-01 23:27:0149using net::test::IsError;
50using net::test::IsOk;
51
xunjieli11834f02015-12-22 04:27:0852namespace net {
53
54namespace {
55
56const char kBodyData[] = "Body data";
Daniel Cheng5feb16f2022-02-28 06:52:0757const size_t kBodyDataSize = std::size(kBodyData);
Bence Békyd74f4382018-02-20 18:26:1958const std::string kBodyDataString(kBodyData, kBodyDataSize);
xunjieli11834f02015-12-22 04:27:0859// Size of the buffer to be allocated for each read.
60const size_t kReadBufferSize = 4096;
61
xunjieli369d0922016-09-23 18:45:0662// Expects that fields of |load_timing_info| are valid time stamps.
63void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info) {
64 EXPECT_FALSE(load_timing_info.request_start.is_null());
65 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
66 EXPECT_FALSE(load_timing_info.receive_headers_end.is_null());
67 EXPECT_FALSE(load_timing_info.send_start.is_null());
68 EXPECT_FALSE(load_timing_info.send_end.is_null());
Maks Orlovich19f8f142021-07-02 17:01:1369 EXPECT_TRUE(load_timing_info.request_start <=
xunjieli369d0922016-09-23 18:45:0670 load_timing_info.receive_headers_end);
71 EXPECT_TRUE(load_timing_info.send_start <= load_timing_info.send_end);
72}
73
74// Tests the load timing of a stream that's connected and is not the first
75// request sent on a connection.
76void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
77 EXPECT_TRUE(load_timing_info.socket_reused);
78
79 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
80 ExpectLoadTimingValid(load_timing_info);
81}
82
83// Tests the load timing of a stream that's connected and using a fresh
84// connection.
85void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info) {
86 EXPECT_FALSE(load_timing_info.socket_reused);
87
88 ExpectConnectTimingHasTimes(
89 load_timing_info.connect_timing,
90 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
91 ExpectLoadTimingValid(load_timing_info);
92}
93
xunjieli11834f02015-12-22 04:27:0894// Delegate that reads data but does not send any data.
95class TestDelegateBase : public BidirectionalStream::Delegate {
96 public:
97 TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
98 : TestDelegateBase(read_buf,
99 read_buf_len,
tzik08d8d6e2018-07-09 04:11:47100 std::make_unique<base::OneShotTimer>()) {}
xunjieli11834f02015-12-22 04:27:08101
102 TestDelegateBase(IOBuffer* read_buf,
103 int read_buf_len,
tzik08d8d6e2018-07-09 04:11:47104 std::unique_ptr<base::OneShotTimer> timer)
xunjieli11834f02015-12-22 04:27:08105 : read_buf_(read_buf),
106 read_buf_len_(read_buf_len),
Tsuyoshi Horo432981d52022-06-09 09:50:13107 timer_(std::move(timer)) {}
xunjieli11834f02015-12-22 04:27:08108
Peter Boström293b1342021-09-22 17:31:43109 TestDelegateBase(const TestDelegateBase&) = delete;
110 TestDelegateBase& operator=(const TestDelegateBase&) = delete;
111
Chris Watkins7a41d3552017-12-01 02:13:27112 ~TestDelegateBase() override = default;
xunjieli11834f02015-12-22 04:27:08113
xunjielibcb0f86e2016-06-03 00:49:29114 void OnStreamReady(bool request_headers_sent) override {
115 // Request headers should always be sent in H2's case, because the
116 // functionality to combine header frame with data frames is not
117 // implemented.
118 EXPECT_TRUE(request_headers_sent);
xunjieli07a42ce2016-04-26 20:05:31119 if (callback_.is_null())
120 return;
Bence Békya4a50932018-08-10 13:39:41121 std::move(callback_).Run(OK);
xunjieli07a42ce2016-04-26 20:05:31122 }
xunjieli11834f02015-12-22 04:27:08123
Ryan Hamilton0239aac2018-05-19 00:03:13124 void OnHeadersReceived(
Bence Béky4c325e52020-10-22 20:48:01125 const spdy::Http2HeaderBlock& response_headers) override {
xunjieli11834f02015-12-22 04:27:08126 CHECK(!not_expect_callback_);
127
bnc94893a72016-06-30 13:45:25128 response_headers_ = response_headers.Clone();
xunjieli9ff75c562016-08-10 20:26:16129
xunjieli11834f02015-12-22 04:27:08130 if (!do_not_start_read_)
131 StartOrContinueReading();
132 }
133
134 void OnDataRead(int bytes_read) override {
135 CHECK(!not_expect_callback_);
136
137 ++on_data_read_count_;
138 CHECK_GE(bytes_read, OK);
139 data_received_.append(read_buf_->data(), bytes_read);
140 if (!do_not_start_read_)
141 StartOrContinueReading();
142 }
143
144 void OnDataSent() override {
145 CHECK(!not_expect_callback_);
146
147 ++on_data_sent_count_;
148 }
149
Bence Béky4c325e52020-10-22 20:48:01150 void OnTrailersReceived(const spdy::Http2HeaderBlock& trailers) override {
xunjieli11834f02015-12-22 04:27:08151 CHECK(!not_expect_callback_);
152
bnc94893a72016-06-30 13:45:25153 trailers_ = trailers.Clone();
xunjieli11834f02015-12-22 04:27:08154 if (run_until_completion_)
155 loop_->Quit();
156 }
157
158 void OnFailed(int error) override {
159 CHECK(!not_expect_callback_);
160 CHECK_EQ(OK, error_);
161 CHECK_NE(OK, error);
162
163 error_ = error;
164 if (run_until_completion_)
165 loop_->Quit();
166 }
167
danakj1fd259a02016-04-16 03:17:09168 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
xunjieli11834f02015-12-22 04:27:08169 HttpNetworkSession* session) {
Peter Boström8a7540692021-04-05 20:48:20170 stream_ = std::make_unique<BidirectionalStream>(
171 std::move(request_info), session, true, this, std::move(timer_));
xunjieli07a42ce2016-04-26 20:05:31172 if (run_until_completion_)
173 loop_->Run();
174 }
175
176 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
177 HttpNetworkSession* session,
Bence Békya4a50932018-08-10 13:39:41178 CompletionOnceCallback cb) {
179 callback_ = std::move(cb);
Peter Boström8a7540692021-04-05 20:48:20180 stream_ = std::make_unique<BidirectionalStream>(
181 std::move(request_info), session, true, this, std::move(timer_));
xunjieli11834f02015-12-22 04:27:08182 if (run_until_completion_)
xunjieli369d0922016-09-23 18:45:06183 WaitUntilCompletion();
xunjieli11834f02015-12-22 04:27:08184 }
185
xunjieli369d0922016-09-23 18:45:06186 void WaitUntilCompletion() { loop_->Run(); }
187
xunjieli2328a2682016-05-16 19:38:25188 void SendData(const scoped_refptr<IOBuffer>& data,
189 int length,
190 bool end_of_stream) {
rchad39988f2017-06-02 05:34:32191 SendvData({data}, {length}, end_of_stream);
xunjieli11834f02015-12-22 04:27:08192 }
193
xunjieli2328a2682016-05-16 19:38:25194 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& data,
xunjieli07a42ce2016-04-26 20:05:31195 const std::vector<int>& length,
196 bool end_of_stream) {
197 not_expect_callback_ = true;
198 stream_->SendvData(data, length, end_of_stream);
199 not_expect_callback_ = false;
200 }
201
xunjieli11834f02015-12-22 04:27:08202 // Starts or continues reading data from |stream_| until no more bytes
203 // can be read synchronously.
204 void StartOrContinueReading() {
205 int rv = ReadData();
206 while (rv > 0) {
207 rv = ReadData();
208 }
209 if (run_until_completion_ && rv == 0)
210 loop_->Quit();
211 }
212
213 // Calls ReadData on the |stream_| and updates internal states.
214 int ReadData() {
215 not_expect_callback_ = true;
216 int rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
217 not_expect_callback_ = false;
218 if (rv > 0)
219 data_received_.append(read_buf_->data(), rv);
220 return rv;
221 }
222
xunjieli11834f02015-12-22 04:27:08223 // Deletes |stream_|.
xunjieli9ff75c562016-08-10 20:26:16224 void DeleteStream() {
225 next_proto_ = stream_->GetProtocol();
226 received_bytes_ = stream_->GetTotalReceivedBytes();
227 sent_bytes_ = stream_->GetTotalSentBytes();
xunjieli369d0922016-09-23 18:45:06228 stream_->GetLoadTimingInfo(&load_timing_info_);
xunjieli9ff75c562016-08-10 20:26:16229 stream_.reset();
xunjieli11834f02015-12-22 04:27:08230 }
231
xunjieli9ff75c562016-08-10 20:26:16232 NextProto GetProtocol() const {
233 if (stream_)
234 return stream_->GetProtocol();
235 return next_proto_;
236 }
237
238 int64_t GetTotalReceivedBytes() const {
239 if (stream_)
240 return stream_->GetTotalReceivedBytes();
241 return received_bytes_;
242 }
243
244 int64_t GetTotalSentBytes() const {
245 if (stream_)
246 return stream_->GetTotalSentBytes();
247 return sent_bytes_;
248 }
xunjieli11834f02015-12-22 04:27:08249
xunjieli369d0922016-09-23 18:45:06250 void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
251 if (stream_) {
252 stream_->GetLoadTimingInfo(load_timing_info);
253 return;
254 }
255 *load_timing_info = load_timing_info_;
256 }
257
xunjieli11834f02015-12-22 04:27:08258 // Const getters for internal states.
259 const std::string& data_received() const { return data_received_; }
260 int error() const { return error_; }
Bence Béky4c325e52020-10-22 20:48:01261 const spdy::Http2HeaderBlock& response_headers() const {
Ryan Hamilton0239aac2018-05-19 00:03:13262 return response_headers_;
263 }
Bence Béky4c325e52020-10-22 20:48:01264 const spdy::Http2HeaderBlock& trailers() const { return trailers_; }
xunjieli11834f02015-12-22 04:27:08265 int on_data_read_count() const { return on_data_read_count_; }
266 int on_data_sent_count() const { return on_data_sent_count_; }
267
268 // Sets whether the delegate should automatically start reading.
269 void set_do_not_start_read(bool do_not_start_read) {
270 do_not_start_read_ = do_not_start_read;
271 }
272 // Sets whether the delegate should wait until the completion of the stream.
273 void SetRunUntilCompletion(bool run_until_completion) {
274 run_until_completion_ = run_until_completion;
Peter Boström8a7540692021-04-05 20:48:20275 loop_ = std::make_unique<base::RunLoop>();
xunjieli11834f02015-12-22 04:27:08276 }
277
278 protected:
279 // Quits |loop_|.
280 void QuitLoop() { loop_->Quit(); }
281
282 private:
danakj1fd259a02016-04-16 03:17:09283 std::unique_ptr<BidirectionalStream> stream_;
xunjieli11834f02015-12-22 04:27:08284 scoped_refptr<IOBuffer> read_buf_;
285 int read_buf_len_;
tzik08d8d6e2018-07-09 04:11:47286 std::unique_ptr<base::OneShotTimer> timer_;
xunjieli11834f02015-12-22 04:27:08287 std::string data_received_;
danakj1fd259a02016-04-16 03:17:09288 std::unique_ptr<base::RunLoop> loop_;
Bence Béky4c325e52020-10-22 20:48:01289 spdy::Http2HeaderBlock response_headers_;
290 spdy::Http2HeaderBlock trailers_;
xunjieli9ff75c562016-08-10 20:26:16291 NextProto next_proto_;
Tsuyoshi Horo432981d52022-06-09 09:50:13292 int64_t received_bytes_ = 0;
293 int64_t sent_bytes_ = 0;
xunjieli369d0922016-09-23 18:45:06294 LoadTimingInfo load_timing_info_;
Tsuyoshi Horo432981d52022-06-09 09:50:13295 int error_ = OK;
296 int on_data_read_count_ = 0;
297 int on_data_sent_count_ = 0;
298 bool do_not_start_read_ = false;
299 bool run_until_completion_ = false;
xunjieli11834f02015-12-22 04:27:08300 // This is to ensure that delegate callback is not invoked synchronously when
301 // calling into |stream_|.
Tsuyoshi Horo432981d52022-06-09 09:50:13302 bool not_expect_callback_ = false;
xunjieli11834f02015-12-22 04:27:08303
Bence Békya4a50932018-08-10 13:39:41304 CompletionOnceCallback callback_;
xunjieli11834f02015-12-22 04:27:08305};
306
307// A delegate that deletes the stream in a particular callback.
xunjieli9ff75c562016-08-10 20:26:16308class DeleteStreamDelegate : public TestDelegateBase {
xunjieli11834f02015-12-22 04:27:08309 public:
310 // Specifies in which callback the stream can be deleted.
311 enum Phase {
312 ON_HEADERS_RECEIVED,
313 ON_DATA_READ,
314 ON_TRAILERS_RECEIVED,
315 ON_FAILED,
316 };
317
xunjieli9ff75c562016-08-10 20:26:16318 DeleteStreamDelegate(IOBuffer* buf, int buf_len, Phase phase)
319 : TestDelegateBase(buf, buf_len), phase_(phase) {}
Peter Boström293b1342021-09-22 17:31:43320
321 DeleteStreamDelegate(const DeleteStreamDelegate&) = delete;
322 DeleteStreamDelegate& operator=(const DeleteStreamDelegate&) = delete;
323
Chris Watkins7a41d3552017-12-01 02:13:27324 ~DeleteStreamDelegate() override = default;
xunjieli11834f02015-12-22 04:27:08325
Ryan Hamilton0239aac2018-05-19 00:03:13326 void OnHeadersReceived(
Bence Béky4c325e52020-10-22 20:48:01327 const spdy::Http2HeaderBlock& response_headers) override {
xunjieli11834f02015-12-22 04:27:08328 TestDelegateBase::OnHeadersReceived(response_headers);
329 if (phase_ == ON_HEADERS_RECEIVED) {
xunjieli9ff75c562016-08-10 20:26:16330 DeleteStream();
xunjieli11834f02015-12-22 04:27:08331 QuitLoop();
332 }
333 }
334
335 void OnDataSent() override { NOTREACHED(); }
336
337 void OnDataRead(int bytes_read) override {
338 if (phase_ == ON_HEADERS_RECEIVED) {
339 NOTREACHED();
340 return;
341 }
342 TestDelegateBase::OnDataRead(bytes_read);
343 if (phase_ == ON_DATA_READ) {
xunjieli9ff75c562016-08-10 20:26:16344 DeleteStream();
xunjieli11834f02015-12-22 04:27:08345 QuitLoop();
346 }
347 }
348
Bence Béky4c325e52020-10-22 20:48:01349 void OnTrailersReceived(const spdy::Http2HeaderBlock& trailers) override {
xunjieli11834f02015-12-22 04:27:08350 if (phase_ == ON_HEADERS_RECEIVED || phase_ == ON_DATA_READ) {
351 NOTREACHED();
352 return;
353 }
354 TestDelegateBase::OnTrailersReceived(trailers);
355 if (phase_ == ON_TRAILERS_RECEIVED) {
xunjieli9ff75c562016-08-10 20:26:16356 DeleteStream();
xunjieli11834f02015-12-22 04:27:08357 QuitLoop();
358 }
359 }
360
361 void OnFailed(int error) override {
362 if (phase_ != ON_FAILED) {
363 NOTREACHED();
364 return;
365 }
366 TestDelegateBase::OnFailed(error);
xunjieli9ff75c562016-08-10 20:26:16367 DeleteStream();
xunjieli11834f02015-12-22 04:27:08368 QuitLoop();
369 }
370
371 private:
xunjieli11834f02015-12-22 04:27:08372 // Indicates in which callback the delegate should cancel or delete the
373 // stream.
374 Phase phase_;
xunjieli11834f02015-12-22 04:27:08375};
376
377// A Timer that does not start a delayed task unless the timer is fired.
tzik35945aa2018-06-22 00:33:26378class MockTimer : public base::MockOneShotTimer {
xunjieli11834f02015-12-22 04:27:08379 public:
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47380 MockTimer() = default;
Peter Boström293b1342021-09-22 17:31:43381
382 MockTimer(const MockTimer&) = delete;
383 MockTimer& operator=(const MockTimer&) = delete;
384
Chris Watkins7a41d3552017-12-01 02:13:27385 ~MockTimer() override = default;
xunjieli11834f02015-12-22 04:27:08386
Brett Wilson9c361992017-09-12 06:05:21387 void Start(const base::Location& posted_from,
xunjieli11834f02015-12-22 04:27:08388 base::TimeDelta delay,
tzikf3336c92018-07-25 03:15:50389 base::OnceClosure user_task) override {
xunjieli11834f02015-12-22 04:27:08390 // Sets a maximum delay, so the timer does not fire unless it is told to.
391 base::TimeDelta infinite_delay = base::TimeDelta::Max();
tzikf3336c92018-07-25 03:15:50392 base::MockOneShotTimer::Start(posted_from, infinite_delay,
393 std::move(user_task));
xunjieli11834f02015-12-22 04:27:08394 }
xunjieli11834f02015-12-22 04:27:08395};
396
397} // namespace
398
Gabriel Charette694c3c332019-08-19 14:53:05399class BidirectionalStreamTest : public TestWithTaskEnvironment {
xunjieli11834f02015-12-22 04:27:08400 public:
401 BidirectionalStreamTest()
bncd16676a2016-07-20 16:23:01402 : default_url_(kDefaultUrl),
bnc3d9035b32016-06-30 18:18:48403 host_port_pair_(HostPortPair::FromURL(default_url_)),
xunjieli11834f02015-12-22 04:27:08404 ssl_data_(SSLSocketDataProvider(ASYNC, OK)) {
bnc3cf2a592016-08-11 14:48:36405 ssl_data_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49406 ssl_data_.ssl_info.cert =
407 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
Matt Reichhoff0049a0b72021-10-20 20:44:26408 net_log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kEverything);
Tsuyoshi Horoc39623a82022-07-11 01:27:58409 auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
410 socket_factory_ = socket_factory.get();
411 session_deps_.socket_factory = std::move(socket_factory);
xunjieli11834f02015-12-22 04:27:08412 }
413
414 protected:
415 void TearDown() override {
416 if (sequenced_data_) {
417 EXPECT_TRUE(sequenced_data_->AllReadDataConsumed());
418 EXPECT_TRUE(sequenced_data_->AllWriteDataConsumed());
419 }
420 }
421
422 // Initializes the session using SequencedSocketData.
Ryan Sleevib8d7ea02018-05-07 20:01:01423 void InitSession(base::span<const MockRead> reads,
424 base::span<const MockWrite> writes,
Paul Jensen76bfe082018-02-23 03:36:05425 const SocketTag& socket_tag) {
Ryan Sleevi4f832092017-11-21 23:25:49426 ASSERT_TRUE(ssl_data_.ssl_info.cert.get());
xunjieli11834f02015-12-22 04:27:08427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data_);
Peter Boström8a7540692021-04-05 20:48:20428 sequenced_data_ = std::make_unique<SequencedSocketData>(reads, writes);
xunjieli11834f02015-12-22 04:27:08429 session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get());
Matt Reichhoff0049a0b72021-10-20 20:44:26430 session_deps_.net_log = NetLog::Get();
xunjieli11834f02015-12-22 04:27:08431 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
Paul Jensen76bfe082018-02-23 03:36:05432 SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:11433 PRIVACY_MODE_DISABLED,
dalyk51ab46b2019-10-15 15:14:34434 SpdySessionKey::IsProxySession::kFalse, socket_tag,
Ben Schwartz3ff4dc1e62021-04-27 21:15:23435 NetworkIsolationKey(), SecureDnsPolicy::kAllow);
Matt Reichhoff0049a0b72021-10-20 20:44:26436 session_ =
437 CreateSpdySession(http_session_.get(), key,
438 NetLogWithSource::Make(NetLogSourceType::NONE));
xunjieli11834f02015-12-22 04:27:08439 }
440
Matt Reichhoff0049a0b72021-10-20 20:44:26441 RecordingNetLogObserver net_log_observer_;
xunjieli11834f02015-12-22 04:27:08442 SpdyTestUtil spdy_util_;
443 SpdySessionDependencies session_deps_;
bnc3d9035b32016-06-30 18:18:48444 const GURL default_url_;
445 const HostPortPair host_port_pair_;
danakj1fd259a02016-04-16 03:17:09446 std::unique_ptr<SequencedSocketData> sequenced_data_;
447 std::unique_ptr<HttpNetworkSession> http_session_;
Keishi Hattori0e45c022021-11-27 09:25:52448 raw_ptr<MockTaggingClientSocketFactory> socket_factory_;
xunjieli11834f02015-12-22 04:27:08449
450 private:
451 SSLSocketDataProvider ssl_data_;
452 base::WeakPtr<SpdySession> session_;
453};
454
455TEST_F(BidirectionalStreamTest, CreateInsecureStream) {
Tsuyoshi Horof8861cb2022-07-05 23:50:20456 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:08457 request_info->method = "GET";
458 request_info->url = GURL("http://www.example.org/");
459
460 TestDelegateBase delegate(nullptr, 0);
Tsuyoshi Horof8861cb2022-07-05 23:50:20461 auto session = std::make_unique<HttpNetworkSession>(
mmenke6ddfbea2017-05-31 21:48:41462 SpdySessionDependencies::CreateSessionParams(&session_deps_),
Tsuyoshi Horof8861cb2022-07-05 23:50:20463 SpdySessionDependencies::CreateSessionContext(&session_deps_));
xunjieli11834f02015-12-22 04:27:08464 delegate.SetRunUntilCompletion(true);
465 delegate.Start(std::move(request_info), session.get());
466
robpercival214763f2016-07-01 23:27:01467 EXPECT_THAT(delegate.error(), IsError(ERR_DISALLOWED_URL_SCHEME));
xunjieli11834f02015-12-22 04:27:08468}
469
xunjieli369d0922016-09-23 18:45:06470TEST_F(BidirectionalStreamTest, SimplePostRequest) {
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
xunjieli369d0922016-09-23 18:45:06472 kDefaultUrl, 1, kBodyDataSize, LOW, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:13473 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:19474 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
xunjieli369d0922016-09-23 18:45:06475 MockWrite writes[] = {
476 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
477 };
Ryan Hamilton0239aac2018-05-19 00:03:13478 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
479 spdy::SpdySerializedFrame response_body_frame(
xunjieli369d0922016-09-23 18:45:06480 spdy_util_.ConstructSpdyDataFrame(1, /*fin=*/true));
481 MockRead reads[] = {
482 CreateMockRead(resp, 1),
483 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
484 CreateMockRead(response_body_frame, 4), MockRead(ASYNC, 0, 5),
485 };
Ryan Sleevib8d7ea02018-05-07 20:01:01486 InitSession(reads, writes, SocketTag());
xunjieli369d0922016-09-23 18:45:06487
Tsuyoshi Horof8861cb2022-07-05 23:50:20488 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli369d0922016-09-23 18:45:06489 request_info->method = "POST";
490 request_info->url = default_url_;
491 request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
Brett Wilson5accd242017-11-30 22:07:32492 base::NumberToString(kBodyDataSize));
Victor Costan9c7302b2018-08-27 16:39:44493 scoped_refptr<IOBuffer> read_buffer =
494 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:20495 auto delegate =
496 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
xunjieli369d0922016-09-23 18:45:06497 delegate->Start(std::move(request_info), http_session_.get());
498 sequenced_data_->RunUntilPaused();
499
Victor Costan9c7302b2018-08-27 16:39:44500 scoped_refptr<StringIOBuffer> buf =
501 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
Bence Békyd74f4382018-02-20 18:26:19502 delegate->SendData(buf.get(), buf->size(), true);
xunjieli369d0922016-09-23 18:45:06503 sequenced_data_->Resume();
504 base::RunLoop().RunUntilIdle();
505 LoadTimingInfo load_timing_info;
506 delegate->GetLoadTimingInfo(&load_timing_info);
507 TestLoadTimingNotReused(load_timing_info);
508
509 EXPECT_EQ(1, delegate->on_data_read_count());
510 EXPECT_EQ(1, delegate->on_data_sent_count());
511 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:01512 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
513 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli369d0922016-09-23 18:45:06514}
515
Maks Orlovich19f8f142021-07-02 17:01:13516TEST_F(BidirectionalStreamTest, LoadTimingTwoRequests) {
Ryan Hamilton0239aac2018-05-19 00:03:13517 spdy::SpdySerializedFrame req(
Bence Béky27ad0a12018-02-08 00:35:48518 spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/1, LOW));
Ryan Hamilton0239aac2018-05-19 00:03:13519 spdy::SpdySerializedFrame req2(
Bence Béky27ad0a12018-02-08 00:35:48520 spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/3, LOW));
xunjieli369d0922016-09-23 18:45:06521 MockWrite writes[] = {
522 CreateMockWrite(req, 0), CreateMockWrite(req2, 2),
523 };
Ryan Hamilton0239aac2018-05-19 00:03:13524 spdy::SpdySerializedFrame resp(
xunjieli369d0922016-09-23 18:45:06525 spdy_util_.ConstructSpdyGetReply(nullptr, 0, /*stream_id=*/1));
Ryan Hamilton0239aac2018-05-19 00:03:13526 spdy::SpdySerializedFrame resp2(
xunjieli369d0922016-09-23 18:45:06527 spdy_util_.ConstructSpdyGetReply(nullptr, 0, /*stream_id=*/3));
Ryan Hamilton0239aac2018-05-19 00:03:13528 spdy::SpdySerializedFrame resp_body(
xunjieli369d0922016-09-23 18:45:06529 spdy_util_.ConstructSpdyDataFrame(/*stream_id=*/1, /*fin=*/true));
Ryan Hamilton0239aac2018-05-19 00:03:13530 spdy::SpdySerializedFrame resp_body2(
xunjieli369d0922016-09-23 18:45:06531 spdy_util_.ConstructSpdyDataFrame(/*stream_id=*/3, /*fin=*/true));
532 MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(resp_body, 3),
533 CreateMockRead(resp2, 4), CreateMockRead(resp_body2, 5),
534 MockRead(ASYNC, 0, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:01535 InitSession(reads, writes, SocketTag());
xunjieli369d0922016-09-23 18:45:06536
Tsuyoshi Horof8861cb2022-07-05 23:50:20537 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli369d0922016-09-23 18:45:06538 request_info->method = "GET";
539 request_info->url = default_url_;
540 request_info->end_stream_on_headers = true;
Tsuyoshi Horof8861cb2022-07-05 23:50:20541 auto request_info2 = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli369d0922016-09-23 18:45:06542 request_info2->method = "GET";
543 request_info2->url = default_url_;
544 request_info2->end_stream_on_headers = true;
545
Victor Costan9c7302b2018-08-27 16:39:44546 scoped_refptr<IOBuffer> read_buffer =
547 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
548 scoped_refptr<IOBuffer> read_buffer2 =
549 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:20550 auto delegate =
551 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
552 auto delegate2 =
553 std::make_unique<TestDelegateBase>(read_buffer2.get(), kReadBufferSize);
xunjieli369d0922016-09-23 18:45:06554 delegate->Start(std::move(request_info), http_session_.get());
555 delegate2->Start(std::move(request_info2), http_session_.get());
556 delegate->SetRunUntilCompletion(true);
557 delegate2->SetRunUntilCompletion(true);
558 base::RunLoop().RunUntilIdle();
559
560 delegate->WaitUntilCompletion();
561 delegate2->WaitUntilCompletion();
562 LoadTimingInfo load_timing_info;
563 delegate->GetLoadTimingInfo(&load_timing_info);
564 TestLoadTimingNotReused(load_timing_info);
565 LoadTimingInfo load_timing_info2;
566 delegate2->GetLoadTimingInfo(&load_timing_info2);
567 TestLoadTimingReused(load_timing_info2);
568}
569
xunjieli3b6ac702016-06-06 21:36:28570// Creates a BidirectionalStream with an insecure scheme. Destroy the stream
571// without waiting for the OnFailed task to be executed.
572TEST_F(BidirectionalStreamTest,
573 CreateInsecureStreamAndDestroyStreamRightAfter) {
Tsuyoshi Horof8861cb2022-07-05 23:50:20574 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli3b6ac702016-06-06 21:36:28575 request_info->method = "GET";
576 request_info->url = GURL("http://www.example.org/");
577
Tsuyoshi Horof8861cb2022-07-05 23:50:20578 auto delegate = std::make_unique<TestDelegateBase>(nullptr, 0);
579 auto session = std::make_unique<HttpNetworkSession>(
mmenke6ddfbea2017-05-31 21:48:41580 SpdySessionDependencies::CreateSessionParams(&session_deps_),
Tsuyoshi Horof8861cb2022-07-05 23:50:20581 SpdySessionDependencies::CreateSessionContext(&session_deps_));
xunjieli3b6ac702016-06-06 21:36:28582 delegate->Start(std::move(request_info), session.get());
583 // Reset stream right before the OnFailed task is executed.
584 delegate.reset();
585
586 base::RunLoop().RunUntilIdle();
587}
588
Helen Li43e3bee2018-03-21 16:57:11589TEST_F(BidirectionalStreamTest, ClientAuthRequestIgnored) {
David Benjamin1c4b6d012019-07-08 17:12:57590 auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
Helen Li43e3bee2018-03-21 16:57:11591 cert_request->host_and_port = host_port_pair_;
592
593 // First attempt receives client auth request.
594 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
595 ssl_data1.next_proto = kProtoHTTP2;
596 ssl_data1.cert_request_info = cert_request.get();
597
598 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:01599 StaticSocketDataProvider socket_data1;
Helen Li43e3bee2018-03-21 16:57:11600 session_deps_.socket_factory->AddSocketDataProvider(&socket_data1);
601
602 // Second attempt succeeds.
Ryan Hamilton0239aac2018-05-19 00:03:13603 spdy::SpdySerializedFrame req(
604 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
Helen Li43e3bee2018-03-21 16:57:11605 MockWrite writes[] = {
606 CreateMockWrite(req, 0),
607 };
Ryan Hamilton0239aac2018-05-19 00:03:13608 spdy::SpdySerializedFrame resp(
609 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
610 spdy::SpdySerializedFrame body_frame(
611 spdy_util_.ConstructSpdyDataFrame(1, true));
Helen Li43e3bee2018-03-21 16:57:11612 MockRead reads[] = {
613 CreateMockRead(resp, 1), CreateMockRead(body_frame, 2),
614 MockRead(SYNCHRONOUS, net::OK, 3),
615 };
616
617 SSLSocketDataProvider ssl_data2(ASYNC, OK);
618 ssl_data2.next_proto = kProtoHTTP2;
619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:01620 SequencedSocketData socket_data2(reads, writes);
Helen Li43e3bee2018-03-21 16:57:11621 session_deps_.socket_factory->AddSocketDataProvider(&socket_data2);
622
623 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
624 SpdySessionKey key(host_port_pair_, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:11625 PRIVACY_MODE_DISABLED,
dalyk51ab46b2019-10-15 15:14:34626 SpdySessionKey::IsProxySession::kFalse, SocketTag(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:23627 NetworkIsolationKey(), SecureDnsPolicy::kAllow);
Tsuyoshi Horof8861cb2022-07-05 23:50:20628 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
Helen Li43e3bee2018-03-21 16:57:11629 request_info->method = "GET";
630 request_info->url = default_url_;
631 request_info->end_stream_on_headers = true;
632 request_info->priority = LOWEST;
633
Victor Costan9c7302b2018-08-27 16:39:44634 scoped_refptr<IOBuffer> read_buffer =
635 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:20636 auto delegate =
637 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
Helen Li43e3bee2018-03-21 16:57:11638
639 delegate->SetRunUntilCompletion(true);
640 delegate->Start(std::move(request_info), http_session_.get());
641
642 // Ensure the certificate was added to the client auth cache.
643 scoped_refptr<X509Certificate> client_cert;
644 scoped_refptr<SSLPrivateKey> client_private_key;
David Benjaminbac8dff2019-08-07 01:30:41645 ASSERT_TRUE(http_session_->ssl_client_context()->GetClientCertificate(
Helen Li43e3bee2018-03-21 16:57:11646 host_port_pair_, &client_cert, &client_private_key));
647 ASSERT_FALSE(client_cert);
648 ASSERT_FALSE(client_private_key);
649
Bence Béky4c325e52020-10-22 20:48:01650 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
Helen Li43e3bee2018-03-21 16:57:11651 EXPECT_EQ("200", response_headers.find(":status")->second);
652 EXPECT_EQ(1, delegate->on_data_read_count());
653 EXPECT_EQ(0, delegate->on_data_sent_count());
654 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
655}
656
xunjieli11834f02015-12-22 04:27:08657// Simulates user calling ReadData after END_STREAM has been received in
xunjieli5749218c2016-03-22 16:43:06658// BidirectionalStreamSpdyImpl.
xunjieli11834f02015-12-22 04:27:08659TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) {
Ryan Hamilton0239aac2018-05-19 00:03:13660 spdy::SpdySerializedFrame req(
661 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
xunjieli11834f02015-12-22 04:27:08662 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:41663 CreateMockWrite(req, 0),
xunjieli11834f02015-12-22 04:27:08664 };
665
666 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
Ryan Hamilton0239aac2018-05-19 00:03:13667 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:15668 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:08669
Ryan Hamilton0239aac2018-05-19 00:03:13670 spdy::SpdySerializedFrame body_frame(
671 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjieli11834f02015-12-22 04:27:08672 // Last body frame has END_STREAM flag set.
Ryan Hamilton0239aac2018-05-19 00:03:13673 spdy::SpdySerializedFrame last_body_frame(
bncdf80d44fd2016-07-15 20:27:41674 spdy_util_.ConstructSpdyDataFrame(1, true));
xunjieli11834f02015-12-22 04:27:08675
676 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:41677 CreateMockRead(resp, 1),
xunjieli11834f02015-12-22 04:27:08678 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41679 CreateMockRead(body_frame, 3),
xunjieli11834f02015-12-22 04:27:08680 MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41681 CreateMockRead(body_frame, 5),
682 CreateMockRead(last_body_frame, 6),
xunjieli11834f02015-12-22 04:27:08683 MockRead(SYNCHRONOUS, 0, 7),
684 };
685
Ryan Sleevib8d7ea02018-05-07 20:01:01686 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:08687
Tsuyoshi Horof8861cb2022-07-05 23:50:20688 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:08689 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:48690 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:08691 request_info->end_stream_on_headers = true;
692 request_info->priority = LOWEST;
693
Victor Costan9c7302b2018-08-27 16:39:44694 scoped_refptr<IOBuffer> read_buffer =
695 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
xunjieli11834f02015-12-22 04:27:08696 // Create a MockTimer. Retain a raw pointer since the underlying
xunjieli5749218c2016-03-22 16:43:06697 // BidirectionalStreamImpl owns it.
Tsuyoshi Horoc39623a82022-07-11 01:27:58698 auto timer = std::make_unique<MockTimer>();
699 MockTimer* timer_ptr = timer.get();
Tsuyoshi Horof8861cb2022-07-05 23:50:20700 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:58701 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjieli11834f02015-12-22 04:27:08702 delegate->set_do_not_start_read(true);
703
704 delegate->Start(std::move(request_info), http_session_.get());
705
706 // Write request, and deliver response headers.
707 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:58708 EXPECT_FALSE(timer_ptr->IsRunning());
xunjieli11834f02015-12-22 04:27:08709 // ReadData returns asynchronously because no data is buffered.
710 int rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:01711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
xunjieli11834f02015-12-22 04:27:08712 // Deliver a DATA frame.
713 sequenced_data_->Resume();
714 base::RunLoop().RunUntilIdle();
Tsuyoshi Horoc39623a82022-07-11 01:27:58715 timer_ptr->Fire();
xunjieli11834f02015-12-22 04:27:08716 // Asynchronous completion callback is invoke.
717 EXPECT_EQ(1, delegate->on_data_read_count());
718 EXPECT_EQ(kUploadDataSize * 1,
719 static_cast<int>(delegate->data_received().size()));
720
721 // Deliver the rest. Note that user has not called a second ReadData.
722 sequenced_data_->Resume();
723 base::RunLoop().RunUntilIdle();
724 // ReadData now. Read should complete synchronously.
725 rv = delegate->ReadData();
726 EXPECT_EQ(kUploadDataSize * 2, rv);
727 rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:01728 EXPECT_THAT(rv, IsOk()); // EOF.
xunjieli11834f02015-12-22 04:27:08729
Bence Béky4c325e52020-10-22 20:48:01730 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjieli11834f02015-12-22 04:27:08731 EXPECT_EQ("200", response_headers.find(":status")->second);
732 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
733 EXPECT_EQ(1, delegate->on_data_read_count());
734 EXPECT_EQ(0, delegate->on_data_sent_count());
735 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:01736 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
737 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:08738}
739
xunjielid4c21ab2016-04-28 22:44:47740// Tests that the NetLog contains correct entries.
741TEST_F(BidirectionalStreamTest, TestNetLogContainEntries) {
Ryan Hamilton0239aac2018-05-19 00:03:13742 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnc3d9035b32016-06-30 18:18:48743 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:13744 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:19745 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
xunjielibe07785e2016-04-14 21:15:29746 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:41747 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
xunjielibe07785e2016-04-14 21:15:29748 };
749
Ryan Hamilton0239aac2018-05-19 00:03:13750 spdy::SpdySerializedFrame resp(
751 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
752 spdy::SpdySerializedFrame response_body_frame1(
bncdf80d44fd2016-07-15 20:27:41753 spdy_util_.ConstructSpdyDataFrame(1, false));
Ryan Hamilton0239aac2018-05-19 00:03:13754 spdy::SpdySerializedFrame response_body_frame2(
bncdf80d44fd2016-07-15 20:27:41755 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjielid4c21ab2016-04-28 22:44:47756
Bence Béky4c325e52020-10-22 20:48:01757 spdy::Http2HeaderBlock trailers;
xunjielid4c21ab2016-04-28 22:44:47758 trailers["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:13759 spdy::SpdySerializedFrame response_trailers(
bnc086b39e12016-06-24 13:05:26760 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers), true));
xunjielibe07785e2016-04-14 21:15:29761
762 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:41763 CreateMockRead(resp, 1),
xunjielibe07785e2016-04-14 21:15:29764 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41765 CreateMockRead(response_body_frame1, 4),
xunjielibe07785e2016-04-14 21:15:29766 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41767 CreateMockRead(response_body_frame2, 6),
768 CreateMockRead(response_trailers, 7),
xunjielid4c21ab2016-04-28 22:44:47769 MockRead(ASYNC, 0, 8),
xunjielibe07785e2016-04-14 21:15:29770 };
771
Ryan Sleevib8d7ea02018-05-07 20:01:01772 InitSession(reads, writes, SocketTag());
xunjielibe07785e2016-04-14 21:15:29773
Tsuyoshi Horof8861cb2022-07-05 23:50:20774 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjielibe07785e2016-04-14 21:15:29775 request_info->method = "POST";
bnc3d9035b32016-06-30 18:18:48776 request_info->url = default_url_;
xunjielibe07785e2016-04-14 21:15:29777 request_info->priority = LOWEST;
Brett Wilson5accd242017-11-30 22:07:32778 request_info->extra_headers.SetHeader(
779 net::HttpRequestHeaders::kContentLength,
780 base::NumberToString(kBodyDataSize * 3));
xunjielibe07785e2016-04-14 21:15:29781
Victor Costan9c7302b2018-08-27 16:39:44782 scoped_refptr<IOBuffer> read_buffer =
783 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:58784 auto timer = std::make_unique<MockTimer>();
785 MockTimer* timer_ptr = timer.get();
Tsuyoshi Horof8861cb2022-07-05 23:50:20786 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:58787 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjielibe07785e2016-04-14 21:15:29788 delegate->set_do_not_start_read(true);
789 delegate->Start(std::move(request_info), http_session_.get());
790 // Send the request and receive response headers.
791 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:58792 EXPECT_FALSE(timer_ptr->IsRunning());
xunjielibe07785e2016-04-14 21:15:29793
Victor Costan9c7302b2018-08-27 16:39:44794 scoped_refptr<StringIOBuffer> buf =
795 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
xunjielibe07785e2016-04-14 21:15:29796 // Send a DATA frame.
xunjieli2328a2682016-05-16 19:38:25797 delegate->SendData(buf, buf->size(), true);
xunjielibe07785e2016-04-14 21:15:29798 // ReadData returns asynchronously because no data is buffered.
799 int rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:01800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
xunjielibe07785e2016-04-14 21:15:29801 // Deliver the first DATA frame.
802 sequenced_data_->Resume();
803 sequenced_data_->RunUntilPaused();
804 // |sequenced_data_| is now stopped after delivering first DATA frame but
805 // before the second DATA frame.
806 // Fire the timer to allow the first ReadData to complete asynchronously.
Tsuyoshi Horoc39623a82022-07-11 01:27:58807 timer_ptr->Fire();
xunjielibe07785e2016-04-14 21:15:29808 base::RunLoop().RunUntilIdle();
809 EXPECT_EQ(1, delegate->on_data_read_count());
810
811 // Now let |sequenced_data_| run until completion.
812 sequenced_data_->Resume();
813 base::RunLoop().RunUntilIdle();
814 // All data has been delivered, and OnClosed() has been invoked.
815 // Read now, and it should complete synchronously.
816 rv = delegate->ReadData();
817 EXPECT_EQ(kUploadDataSize, rv);
818 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
819 EXPECT_EQ(1, delegate->on_data_read_count());
820 EXPECT_EQ(1, delegate->on_data_sent_count());
821 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
xunjielid4c21ab2016-04-28 22:44:47822 EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
Ryan Sleevib8d7ea02018-05-07 20:01:01823 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
824 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjielibe07785e2016-04-14 21:15:29825
xunjielid4c21ab2016-04-28 22:44:47826 // Destroy the delegate will destroy the stream, so we can get an end event
827 // for BIDIRECTIONAL_STREAM_ALIVE.
828 delegate.reset();
Matt Reichhoff0049a0b72021-10-20 20:44:26829 auto entries = net_log_observer_.GetEntries();
xunjieli2704f5d2016-06-10 16:02:23830
xunjielibe07785e2016-04-14 21:15:29831 size_t index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00832 entries, 0, NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
833 NetLogEventPhase::BEGIN);
xunjielif88028e2016-06-01 19:27:14834 // HTTP_STREAM_REQUEST is nested inside in BIDIRECTIONAL_STREAM_ALIVE.
mikecirone8b85c432016-09-08 19:11:00835 index = ExpectLogContainsSomewhere(entries, index,
836 NetLogEventType::HTTP_STREAM_REQUEST,
837 NetLogEventPhase::BEGIN);
838 index = ExpectLogContainsSomewhere(entries, index,
839 NetLogEventType::HTTP_STREAM_REQUEST,
840 NetLogEventPhase::END);
xunjielif88028e2016-06-01 19:27:14841 // Headers received should happen after HTTP_STREAM_REQUEST.
xunjielid4c21ab2016-04-28 22:44:47842 index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00843 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_RECV_HEADERS,
844 NetLogEventPhase::NONE);
xunjielid4c21ab2016-04-28 22:44:47845 // Trailers received should happen after headers received. It might happen
846 // before the reads complete.
mikecirone8b85c432016-09-08 19:11:00847 ExpectLogContainsSomewhere(
848 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_RECV_TRAILERS,
849 NetLogEventPhase::NONE);
xunjielie1780482016-07-01 21:22:54850 index = ExpectLogContainsSomewhere(
rchad39988f2017-06-02 05:34:32851 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA,
mikecirone8b85c432016-09-08 19:11:00852 NetLogEventPhase::NONE);
xunjielie1780482016-07-01 21:22:54853 index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00854 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_READ_DATA,
855 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:54856 EXPECT_EQ(ERR_IO_PENDING, GetIntegerValueFromParams(entries[index], "rv"));
xunjielie1780482016-07-01 21:22:54857
xunjielid4c21ab2016-04-28 22:44:47858 // Sent bytes. Sending data is always asynchronous.
859 index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00860 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
861 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:54862 EXPECT_EQ(NetLogSourceType::BIDIRECTIONAL_STREAM, entries[index].source.type);
xunjielibe07785e2016-04-14 21:15:29863 // Received bytes for asynchronous read.
864 index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00865 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_RECEIVED,
866 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:54867 EXPECT_EQ(NetLogSourceType::BIDIRECTIONAL_STREAM, entries[index].source.type);
xunjielibe07785e2016-04-14 21:15:29868 // Received bytes for synchronous read.
869 index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00870 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_RECEIVED,
871 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:54872 EXPECT_EQ(NetLogSourceType::BIDIRECTIONAL_STREAM, entries[index].source.type);
xunjielid4c21ab2016-04-28 22:44:47873 ExpectLogContainsSomewhere(entries, index,
mikecirone8b85c432016-09-08 19:11:00874 NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
875 NetLogEventPhase::END);
xunjielibe07785e2016-04-14 21:15:29876}
877
xunjieli11834f02015-12-22 04:27:08878TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) {
Ryan Hamilton0239aac2018-05-19 00:03:13879 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnc3d9035b32016-06-30 18:18:48880 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:13881 spdy::SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19882 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/false));
Ryan Hamilton0239aac2018-05-19 00:03:13883 spdy::SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19884 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/false));
Ryan Hamilton0239aac2018-05-19 00:03:13885 spdy::SpdySerializedFrame data_frame3(
Bence Békyd74f4382018-02-20 18:26:19886 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
xunjieli11834f02015-12-22 04:27:08887 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:41888 CreateMockWrite(req, 0), CreateMockWrite(data_frame1, 3),
889 CreateMockWrite(data_frame2, 6), CreateMockWrite(data_frame3, 9),
xunjieli11834f02015-12-22 04:27:08890 };
891
Ryan Hamilton0239aac2018-05-19 00:03:13892 spdy::SpdySerializedFrame resp(
893 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
894 spdy::SpdySerializedFrame response_body_frame1(
bncdf80d44fd2016-07-15 20:27:41895 spdy_util_.ConstructSpdyDataFrame(1, false));
Ryan Hamilton0239aac2018-05-19 00:03:13896 spdy::SpdySerializedFrame response_body_frame2(
bncdf80d44fd2016-07-15 20:27:41897 spdy_util_.ConstructSpdyDataFrame(1, true));
xunjieli11834f02015-12-22 04:27:08898
899 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:41900 CreateMockRead(resp, 1),
xunjieli11834f02015-12-22 04:27:08901 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41902 CreateMockRead(response_body_frame1, 4),
xunjieli11834f02015-12-22 04:27:08903 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41904 CreateMockRead(response_body_frame2, 7),
xunjieli11834f02015-12-22 04:27:08905 MockRead(ASYNC, ERR_IO_PENDING, 8), // Force a pause.
906 MockRead(ASYNC, 0, 10),
907 };
908
Ryan Sleevib8d7ea02018-05-07 20:01:01909 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:08910
Tsuyoshi Horof8861cb2022-07-05 23:50:20911 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:08912 request_info->method = "POST";
bnc3d9035b32016-06-30 18:18:48913 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:08914 request_info->priority = LOWEST;
Brett Wilson5accd242017-11-30 22:07:32915 request_info->extra_headers.SetHeader(
916 net::HttpRequestHeaders::kContentLength,
917 base::NumberToString(kBodyDataSize * 3));
xunjieli11834f02015-12-22 04:27:08918
Victor Costan9c7302b2018-08-27 16:39:44919 scoped_refptr<IOBuffer> read_buffer =
920 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:58921 auto timer = std::make_unique<MockTimer>();
922 MockTimer* timer_ptr = timer.get();
Tsuyoshi Horof8861cb2022-07-05 23:50:20923 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:58924 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjieli11834f02015-12-22 04:27:08925 delegate->set_do_not_start_read(true);
926 delegate->Start(std::move(request_info), http_session_.get());
927 // Send the request and receive response headers.
928 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:58929 EXPECT_FALSE(timer_ptr->IsRunning());
xunjieli11834f02015-12-22 04:27:08930
931 // Send a DATA frame.
Victor Costan9c7302b2018-08-27 16:39:44932 scoped_refptr<StringIOBuffer> buf =
933 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
xunjieli11834f02015-12-22 04:27:08934
935 // Send a DATA frame.
xunjieli2328a2682016-05-16 19:38:25936 delegate->SendData(buf, buf->size(), false);
xunjieli11834f02015-12-22 04:27:08937 // ReadData and it should return asynchronously because no data is buffered.
938 int rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:01939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
xunjieli11834f02015-12-22 04:27:08940 // Deliver a DATA frame, and fire the timer.
941 sequenced_data_->Resume();
942 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:58943 timer_ptr->Fire();
xunjieli11834f02015-12-22 04:27:08944 base::RunLoop().RunUntilIdle();
945 EXPECT_EQ(1, delegate->on_data_sent_count());
946 EXPECT_EQ(1, delegate->on_data_read_count());
947
948 // Send a DATA frame.
xunjieli2328a2682016-05-16 19:38:25949 delegate->SendData(buf, buf->size(), false);
xunjieli11834f02015-12-22 04:27:08950 // ReadData and it should return asynchronously because no data is buffered.
951 rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:01952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
xunjieli11834f02015-12-22 04:27:08953 // Deliver a DATA frame, and fire the timer.
954 sequenced_data_->Resume();
955 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:58956 timer_ptr->Fire();
xunjieli11834f02015-12-22 04:27:08957 base::RunLoop().RunUntilIdle();
958 // Last DATA frame is read. Server half closes.
959 EXPECT_EQ(2, delegate->on_data_read_count());
960 EXPECT_EQ(2, delegate->on_data_sent_count());
961
962 // Send the last body frame. Client half closes.
xunjieli2328a2682016-05-16 19:38:25963 delegate->SendData(buf, buf->size(), true);
xunjieli11834f02015-12-22 04:27:08964 sequenced_data_->Resume();
965 base::RunLoop().RunUntilIdle();
966 EXPECT_EQ(3, delegate->on_data_sent_count());
967
968 // OnClose is invoked since both sides are closed.
969 rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:01970 EXPECT_THAT(rv, IsOk());
xunjieli11834f02015-12-22 04:27:08971
972 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
973 EXPECT_EQ(2, delegate->on_data_read_count());
974 EXPECT_EQ(3, delegate->on_data_sent_count());
975 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:01976 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
977 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:08978}
979
xunjieli07a42ce2016-04-26 20:05:31980TEST_F(BidirectionalStreamTest, TestCoalesceSmallDataBuffers) {
Ryan Hamilton0239aac2018-05-19 00:03:13981 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnc3d9035b32016-06-30 18:18:48982 kDefaultUrl, 1, kBodyDataSize * 1, LOWEST, nullptr, 0));
xunjieli07a42ce2016-04-26 20:05:31983 std::string body_data = "some really long piece of data";
Ryan Hamilton0239aac2018-05-19 00:03:13984 spdy::SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19985 spdy_util_.ConstructSpdyDataFrame(1, body_data, /*fin=*/true));
xunjieli07a42ce2016-04-26 20:05:31986 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:41987 CreateMockWrite(req, 0), CreateMockWrite(data_frame1, 1),
xunjieli07a42ce2016-04-26 20:05:31988 };
989
Ryan Hamilton0239aac2018-05-19 00:03:13990 spdy::SpdySerializedFrame resp(
991 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
992 spdy::SpdySerializedFrame response_body_frame1(
bncdf80d44fd2016-07-15 20:27:41993 spdy_util_.ConstructSpdyDataFrame(1, true));
xunjieli07a42ce2016-04-26 20:05:31994 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:41995 CreateMockRead(resp, 2),
xunjieli07a42ce2016-04-26 20:05:31996 MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause.
bncdf80d44fd2016-07-15 20:27:41997 CreateMockRead(response_body_frame1, 4), MockRead(ASYNC, 0, 5),
xunjieli07a42ce2016-04-26 20:05:31998 };
999
Ryan Sleevib8d7ea02018-05-07 20:01:011000 InitSession(reads, writes, SocketTag());
xunjieli07a42ce2016-04-26 20:05:311001
Tsuyoshi Horof8861cb2022-07-05 23:50:201002 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli07a42ce2016-04-26 20:05:311003 request_info->method = "POST";
bnc3d9035b32016-06-30 18:18:481004 request_info->url = default_url_;
xunjieli07a42ce2016-04-26 20:05:311005 request_info->priority = LOWEST;
Brett Wilson5accd242017-11-30 22:07:321006 request_info->extra_headers.SetHeader(
1007 net::HttpRequestHeaders::kContentLength,
1008 base::NumberToString(kBodyDataSize * 1));
xunjieli07a42ce2016-04-26 20:05:311009
Victor Costan9c7302b2018-08-27 16:39:441010 scoped_refptr<IOBuffer> read_buffer =
1011 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:581012 auto timer = std::make_unique<MockTimer>();
Tsuyoshi Horof8861cb2022-07-05 23:50:201013 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:581014 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjieli07a42ce2016-04-26 20:05:311015 delegate->set_do_not_start_read(true);
xunjieli07a42ce2016-04-26 20:05:311016 TestCompletionCallback callback;
1017 delegate->Start(std::move(request_info), http_session_.get(),
1018 callback.callback());
1019 // Wait until the stream is ready.
1020 callback.WaitForResult();
1021 // Send a DATA frame.
Victor Costan9c7302b2018-08-27 16:39:441022 scoped_refptr<StringIOBuffer> buf =
1023 base::MakeRefCounted<StringIOBuffer>(body_data.substr(0, 5));
1024 scoped_refptr<StringIOBuffer> buf2 = base::MakeRefCounted<StringIOBuffer>(
1025 body_data.substr(5, body_data.size() - 5));
xunjieli2328a2682016-05-16 19:38:251026 delegate->SendvData({buf, buf2.get()}, {buf->size(), buf2->size()}, true);
xunjieli07a42ce2016-04-26 20:05:311027 sequenced_data_->RunUntilPaused(); // OnHeadersReceived.
1028 // ReadData and it should return asynchronously because no data is buffered.
robpercival214763f2016-07-01 23:27:011029 EXPECT_THAT(delegate->ReadData(), IsError(ERR_IO_PENDING));
xunjieli07a42ce2016-04-26 20:05:311030 sequenced_data_->Resume();
1031 base::RunLoop().RunUntilIdle();
1032 EXPECT_EQ(1, delegate->on_data_sent_count());
1033 EXPECT_EQ(1, delegate->on_data_read_count());
1034
1035 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1036 EXPECT_EQ(1, delegate->on_data_read_count());
1037 EXPECT_EQ(1, delegate->on_data_sent_count());
1038 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:011039 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1040 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli2704f5d2016-06-10 16:02:231041
Matt Reichhoff0049a0b72021-10-20 20:44:261042 auto entries = net_log_observer_.GetEntries();
xunjieli2704f5d2016-06-10 16:02:231043 size_t index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001044 entries, 0, NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA,
1045 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:541046 EXPECT_EQ(2, GetIntegerValueFromParams(entries[index], "num_buffers"));
xunjielie1780482016-07-01 21:22:541047
1048 index = ExpectLogContainsSomewhereAfter(
mikecirone8b85c432016-09-08 19:11:001049 entries, index,
1050 NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED,
1051 NetLogEventPhase::BEGIN);
Eric Roman79cc7552019-07-19 02:17:541052 EXPECT_EQ(2,
1053 GetIntegerValueFromParams(entries[index], "num_buffers_coalesced"));
xunjieli2704f5d2016-06-10 16:02:231054
1055 index = ExpectLogContainsSomewhereAfter(
mikecirone8b85c432016-09-08 19:11:001056 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
1057 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:541058 EXPECT_EQ(buf->size(),
1059 GetIntegerValueFromParams(entries[index], "byte_count"));
xunjieli2704f5d2016-06-10 16:02:231060
1061 index = ExpectLogContainsSomewhereAfter(
mikecirone8b85c432016-09-08 19:11:001062 entries, index + 1, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
1063 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:541064 EXPECT_EQ(buf2->size(),
1065 GetIntegerValueFromParams(entries[index], "byte_count"));
xunjieli2704f5d2016-06-10 16:02:231066
1067 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001068 entries, index,
1069 NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED,
1070 NetLogEventPhase::END);
xunjieli07a42ce2016-04-26 20:05:311071}
1072
xunjieli5749218c2016-03-22 16:43:061073// Tests that BidirectionalStreamSpdyImpl::OnClose will complete any remaining
xunjieli11834f02015-12-22 04:27:081074// read even if the read queue is empty.
1075TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) {
Ryan Hamilton0239aac2018-05-19 00:03:131076 spdy::SpdySerializedFrame req(
1077 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:411078 MockWrite writes[] = {CreateMockWrite(req, 0)};
xunjieli11834f02015-12-22 04:27:081079
Ryan Hamilton0239aac2018-05-19 00:03:131080 spdy::SpdySerializedFrame resp(
1081 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
xunjieli11834f02015-12-22 04:27:081082
Ryan Hamilton0239aac2018-05-19 00:03:131083 spdy::SpdySerializedFrame response_body_frame(
Bence Békyd74f4382018-02-20 18:26:191084 spdy_util_.ConstructSpdyDataFrame(1, "", true));
xunjieli11834f02015-12-22 04:27:081085
1086 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411087 CreateMockRead(resp, 1),
xunjieli11834f02015-12-22 04:27:081088 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
bncdf80d44fd2016-07-15 20:27:411089 CreateMockRead(response_body_frame, 3), MockRead(SYNCHRONOUS, 0, 4),
xunjieli11834f02015-12-22 04:27:081090 };
1091
Ryan Sleevib8d7ea02018-05-07 20:01:011092 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081093
Tsuyoshi Horof8861cb2022-07-05 23:50:201094 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081095 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481096 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081097 request_info->priority = LOWEST;
1098 request_info->end_stream_on_headers = true;
1099
Victor Costan9c7302b2018-08-27 16:39:441100 scoped_refptr<IOBuffer> read_buffer =
1101 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:581102 auto timer = std::make_unique<MockTimer>();
1103 MockTimer* timer_ptr = timer.get();
Tsuyoshi Horof8861cb2022-07-05 23:50:201104 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:581105 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjieli11834f02015-12-22 04:27:081106 delegate->set_do_not_start_read(true);
1107 delegate->Start(std::move(request_info), http_session_.get());
1108 // Write request, and deliver response headers.
1109 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:581110 EXPECT_FALSE(timer_ptr->IsRunning());
xunjieli11834f02015-12-22 04:27:081111
1112 // ReadData should return asynchronously because no data is buffered.
1113 int rv = delegate->ReadData();
robpercival214763f2016-07-01 23:27:011114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
xunjieli11834f02015-12-22 04:27:081115 // Deliver END_STREAM.
1116 // OnClose should trigger completion of the remaining read.
1117 sequenced_data_->Resume();
1118 base::RunLoop().RunUntilIdle();
1119
1120 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1121 EXPECT_EQ(1, delegate->on_data_read_count());
1122 EXPECT_EQ(0u, delegate->data_received().size());
1123 EXPECT_EQ(0, delegate->on_data_sent_count());
1124 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:011125 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1126 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081127}
1128
1129TEST_F(BidirectionalStreamTest, TestBuffering) {
Ryan Hamilton0239aac2018-05-19 00:03:131130 spdy::SpdySerializedFrame req(
1131 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:411132 MockWrite writes[] = {CreateMockWrite(req, 0)};
xunjieli11834f02015-12-22 04:27:081133
1134 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
Ryan Hamilton0239aac2018-05-19 00:03:131135 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151136 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081137
Ryan Hamilton0239aac2018-05-19 00:03:131138 spdy::SpdySerializedFrame body_frame(
1139 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjieli11834f02015-12-22 04:27:081140 // Last body frame has END_STREAM flag set.
Ryan Hamilton0239aac2018-05-19 00:03:131141 spdy::SpdySerializedFrame last_body_frame(
bncdf80d44fd2016-07-15 20:27:411142 spdy_util_.ConstructSpdyDataFrame(1, true));
xunjieli11834f02015-12-22 04:27:081143
1144 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411145 CreateMockRead(resp, 1),
1146 CreateMockRead(body_frame, 2),
1147 CreateMockRead(body_frame, 3),
xunjieli11834f02015-12-22 04:27:081148 MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
bncdf80d44fd2016-07-15 20:27:411149 CreateMockRead(last_body_frame, 5),
xunjieli11834f02015-12-22 04:27:081150 MockRead(SYNCHRONOUS, 0, 6),
1151 };
1152
Ryan Sleevib8d7ea02018-05-07 20:01:011153 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081154
Tsuyoshi Horof8861cb2022-07-05 23:50:201155 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081156 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481157 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081158 request_info->priority = LOWEST;
1159 request_info->end_stream_on_headers = true;
1160
Victor Costan9c7302b2018-08-27 16:39:441161 scoped_refptr<IOBuffer> read_buffer =
1162 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:581163 auto timer = std::make_unique<MockTimer>();
1164 MockTimer* timer_ptr = timer.get();
Tsuyoshi Horof8861cb2022-07-05 23:50:201165 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:581166 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjieli11834f02015-12-22 04:27:081167 delegate->Start(std::move(request_info), http_session_.get());
1168 // Deliver two DATA frames together.
1169 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:581170 EXPECT_TRUE(timer_ptr->IsRunning());
1171 timer_ptr->Fire();
xunjieli11834f02015-12-22 04:27:081172 base::RunLoop().RunUntilIdle();
1173 // This should trigger |more_read_data_pending_| to execute the task at a
1174 // later time, and Delegate::OnReadComplete should not have been called.
Tsuyoshi Horoc39623a82022-07-11 01:27:581175 EXPECT_TRUE(timer_ptr->IsRunning());
xunjieli11834f02015-12-22 04:27:081176 EXPECT_EQ(0, delegate->on_data_read_count());
1177
1178 // Fire the timer now, the two DATA frame should be combined into one
1179 // single Delegate::OnReadComplete callback.
Tsuyoshi Horoc39623a82022-07-11 01:27:581180 timer_ptr->Fire();
xunjieli11834f02015-12-22 04:27:081181 base::RunLoop().RunUntilIdle();
1182 EXPECT_EQ(1, delegate->on_data_read_count());
1183 EXPECT_EQ(kUploadDataSize * 2,
1184 static_cast<int>(delegate->data_received().size()));
1185
1186 // Deliver last DATA frame and EOF. There will be an additional
1187 // Delegate::OnReadComplete callback.
1188 sequenced_data_->Resume();
xunjieli62f67822016-06-01 18:29:271189 base::RunLoop().RunUntilIdle();
1190
xunjieli11834f02015-12-22 04:27:081191 EXPECT_EQ(2, delegate->on_data_read_count());
1192 EXPECT_EQ(kUploadDataSize * 3,
1193 static_cast<int>(delegate->data_received().size()));
1194
Bence Béky4c325e52020-10-22 20:48:011195 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjieli11834f02015-12-22 04:27:081196 EXPECT_EQ("200", response_headers.find(":status")->second);
1197 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1198 EXPECT_EQ(0, delegate->on_data_sent_count());
1199 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:011200 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1201 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081202}
1203
1204TEST_F(BidirectionalStreamTest, TestBufferingWithTrailers) {
Ryan Hamilton0239aac2018-05-19 00:03:131205 spdy::SpdySerializedFrame req(
1206 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
xunjieli11834f02015-12-22 04:27:081207 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411208 CreateMockWrite(req, 0),
xunjieli11834f02015-12-22 04:27:081209 };
1210
1211 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
Ryan Hamilton0239aac2018-05-19 00:03:131212 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151213 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081214
Ryan Hamilton0239aac2018-05-19 00:03:131215 spdy::SpdySerializedFrame body_frame(
1216 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjieli11834f02015-12-22 04:27:081217
Bence Béky4c325e52020-10-22 20:48:011218 spdy::Http2HeaderBlock trailers;
xunjielid4c21ab2016-04-28 22:44:471219 trailers["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:131220 spdy::SpdySerializedFrame response_trailers(
bnc086b39e12016-06-24 13:05:261221 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers), true));
xunjieli11834f02015-12-22 04:27:081222
1223 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411224 CreateMockRead(resp, 1),
1225 CreateMockRead(body_frame, 2),
1226 CreateMockRead(body_frame, 3),
1227 CreateMockRead(body_frame, 4),
xunjieli11834f02015-12-22 04:27:081228 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
bncdf80d44fd2016-07-15 20:27:411229 CreateMockRead(response_trailers, 6),
xunjielid4c21ab2016-04-28 22:44:471230 MockRead(SYNCHRONOUS, 0, 7),
xunjieli11834f02015-12-22 04:27:081231 };
1232
Ryan Sleevib8d7ea02018-05-07 20:01:011233 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081234
Victor Costan9c7302b2018-08-27 16:39:441235 scoped_refptr<IOBuffer> read_buffer =
1236 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:581237 auto timer = std::make_unique<MockTimer>();
1238 MockTimer* timer_ptr = timer.get();
Tsuyoshi Horof8861cb2022-07-05 23:50:201239 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:581240 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjieli11834f02015-12-22 04:27:081241
Tsuyoshi Horof8861cb2022-07-05 23:50:201242 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081243 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481244 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081245 request_info->priority = LOWEST;
1246 request_info->end_stream_on_headers = true;
1247
1248 delegate->Start(std::move(request_info), http_session_.get());
1249 // Deliver all three DATA frames together.
1250 sequenced_data_->RunUntilPaused();
Tsuyoshi Horoc39623a82022-07-11 01:27:581251 EXPECT_TRUE(timer_ptr->IsRunning());
1252 timer_ptr->Fire();
xunjieli11834f02015-12-22 04:27:081253 base::RunLoop().RunUntilIdle();
1254 // This should trigger |more_read_data_pending_| to execute the task at a
1255 // later time, and Delegate::OnReadComplete should not have been called.
Tsuyoshi Horoc39623a82022-07-11 01:27:581256 EXPECT_TRUE(timer_ptr->IsRunning());
xunjieli11834f02015-12-22 04:27:081257 EXPECT_EQ(0, delegate->on_data_read_count());
1258
1259 // Deliver trailers. Remaining read should be completed, since OnClose is
1260 // called right after OnTrailersReceived. The three DATA frames should be
1261 // delivered in a single OnReadCompleted callback.
1262 sequenced_data_->Resume();
xunjieli62f67822016-06-01 18:29:271263 base::RunLoop().RunUntilIdle();
1264
xunjieli11834f02015-12-22 04:27:081265 EXPECT_EQ(1, delegate->on_data_read_count());
1266 EXPECT_EQ(kUploadDataSize * 3,
1267 static_cast<int>(delegate->data_received().size()));
Bence Béky4c325e52020-10-22 20:48:011268 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjieli11834f02015-12-22 04:27:081269 EXPECT_EQ("200", response_headers.find(":status")->second);
1270 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1271 EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
1272 EXPECT_EQ(0, delegate->on_data_sent_count());
1273 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
Ryan Sleevib8d7ea02018-05-07 20:01:011274 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1275 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081276}
1277
xunjieli9ff75c562016-08-10 20:26:161278TEST_F(BidirectionalStreamTest, DeleteStreamAfterSendData) {
Ryan Hamilton0239aac2018-05-19 00:03:131279 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnc3d9035b32016-06-30 18:18:481280 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:131281 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:191282 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/false));
Ryan Hamilton0239aac2018-05-19 00:03:131283 spdy::SpdySerializedFrame rst(
1284 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
xunjieli11834f02015-12-22 04:27:081285
1286 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411287 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
1288 CreateMockWrite(rst, 5),
xunjieli11834f02015-12-22 04:27:081289 };
1290
Ryan Hamilton0239aac2018-05-19 00:03:131291 spdy::SpdySerializedFrame resp(
1292 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
xunjieli11834f02015-12-22 04:27:081293 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411294 CreateMockRead(resp, 1),
xunjieli11834f02015-12-22 04:27:081295 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
1296 MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
1297 MockRead(ASYNC, 0, 6),
1298 };
1299
Ryan Sleevib8d7ea02018-05-07 20:01:011300 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081301
Tsuyoshi Horof8861cb2022-07-05 23:50:201302 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081303 request_info->method = "POST";
bnc3d9035b32016-06-30 18:18:481304 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081305 request_info->priority = LOWEST;
Brett Wilson5accd242017-11-30 22:07:321306 request_info->extra_headers.SetHeader(
1307 net::HttpRequestHeaders::kContentLength,
1308 base::NumberToString(kBodyDataSize * 3));
xunjieli11834f02015-12-22 04:27:081309
Victor Costan9c7302b2018-08-27 16:39:441310 scoped_refptr<IOBuffer> read_buffer =
1311 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201312 auto delegate =
1313 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
xunjieli11834f02015-12-22 04:27:081314 delegate->set_do_not_start_read(true);
1315 delegate->Start(std::move(request_info), http_session_.get());
1316 // Send the request and receive response headers.
1317 sequenced_data_->RunUntilPaused();
1318 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1319
1320 // Send a DATA frame.
Victor Costan9c7302b2018-08-27 16:39:441321 scoped_refptr<StringIOBuffer> buf =
1322 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
xunjieli2328a2682016-05-16 19:38:251323 delegate->SendData(buf, buf->size(), false);
xunjieli11834f02015-12-22 04:27:081324 sequenced_data_->Resume();
1325 base::RunLoop().RunUntilIdle();
xunjieli9ff75c562016-08-10 20:26:161326
1327 delegate->DeleteStream();
xunjieli11834f02015-12-22 04:27:081328 sequenced_data_->Resume();
1329 base::RunLoop().RunUntilIdle();
1330
1331 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1332 EXPECT_EQ(0, delegate->on_data_read_count());
xunjieli11834f02015-12-22 04:27:081333 // OnDataSent may or may not have been invoked.
xunjieli9ff75c562016-08-10 20:26:161334 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1335 // Bytes sent excludes the RST frame.
Ryan Sleevib8d7ea02018-05-07 20:01:011336 EXPECT_EQ(
Daniel Cheng5feb16f2022-02-28 06:52:071337 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
Ryan Sleevib8d7ea02018-05-07 20:01:011338 delegate->GetTotalSentBytes());
1339 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081340}
1341
xunjieli9ff75c562016-08-10 20:26:161342TEST_F(BidirectionalStreamTest, DeleteStreamDuringReadData) {
Ryan Hamilton0239aac2018-05-19 00:03:131343 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnc3d9035b32016-06-30 18:18:481344 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:131345 spdy::SpdySerializedFrame rst(
1346 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
xunjieli11834f02015-12-22 04:27:081347
1348 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411349 CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
xunjieli11834f02015-12-22 04:27:081350 };
1351
Ryan Hamilton0239aac2018-05-19 00:03:131352 spdy::SpdySerializedFrame resp(
1353 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1354 spdy::SpdySerializedFrame response_body_frame(
bncdf80d44fd2016-07-15 20:27:411355 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjieli11834f02015-12-22 04:27:081356
1357 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411358 CreateMockRead(resp, 1),
xunjieli11834f02015-12-22 04:27:081359 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
bncdf80d44fd2016-07-15 20:27:411360 CreateMockRead(response_body_frame, 3), MockRead(ASYNC, 0, 5),
xunjieli11834f02015-12-22 04:27:081361 };
1362
Ryan Sleevib8d7ea02018-05-07 20:01:011363 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081364
Tsuyoshi Horof8861cb2022-07-05 23:50:201365 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081366 request_info->method = "POST";
bnc3d9035b32016-06-30 18:18:481367 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081368 request_info->priority = LOWEST;
Brett Wilson5accd242017-11-30 22:07:321369 request_info->extra_headers.SetHeader(
1370 net::HttpRequestHeaders::kContentLength,
1371 base::NumberToString(kBodyDataSize * 3));
xunjieli11834f02015-12-22 04:27:081372
Victor Costan9c7302b2018-08-27 16:39:441373 scoped_refptr<IOBuffer> read_buffer =
1374 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201375 auto delegate =
1376 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
xunjieli11834f02015-12-22 04:27:081377 delegate->set_do_not_start_read(true);
1378 delegate->Start(std::move(request_info), http_session_.get());
1379 // Send the request and receive response headers.
1380 base::RunLoop().RunUntilIdle();
1381
1382 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
xunjieli9ff75c562016-08-10 20:26:161383 // Delete the stream after ReadData returns ERR_IO_PENDING.
xunjieli11834f02015-12-22 04:27:081384 int rv = delegate->ReadData();
1385 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
robpercival214763f2016-07-01 23:27:011386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
xunjieli9ff75c562016-08-10 20:26:161387 delegate->DeleteStream();
xunjieli11834f02015-12-22 04:27:081388 sequenced_data_->Resume();
1389 base::RunLoop().RunUntilIdle();
1390
1391 EXPECT_EQ(0, delegate->on_data_read_count());
1392 EXPECT_EQ(0, delegate->on_data_sent_count());
xunjieli9ff75c562016-08-10 20:26:161393 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1394 // Bytes sent excludes the RST frame.
Ryan Sleevib8d7ea02018-05-07 20:01:011395 EXPECT_EQ(
Daniel Cheng5feb16f2022-02-28 06:52:071396 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
Ryan Sleevib8d7ea02018-05-07 20:01:011397 delegate->GetTotalSentBytes());
xunjieli9ff75c562016-08-10 20:26:161398 // Response body frame isn't read becase stream is deleted once read returns
1399 // ERR_IO_PENDING.
Daniel Cheng5feb16f2022-02-28 06:52:071400 EXPECT_EQ(CountReadBytes(base::make_span(reads).first(std::size(reads) - 2)),
xunjieli9ff75c562016-08-10 20:26:161401 delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081402}
1403
1404// Receiving a header with uppercase ASCII will result in a protocol error,
1405// which should be propagated via Delegate::OnFailed.
1406TEST_F(BidirectionalStreamTest, PropagateProtocolError) {
Ryan Hamilton0239aac2018-05-19 00:03:131407 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
bnc3d9035b32016-06-30 18:18:481408 kDefaultUrl, 1, kBodyDataSize * 3, LOW, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:131409 spdy::SpdySerializedFrame rst(
1410 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
xunjieli11834f02015-12-22 04:27:081411
1412 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411413 CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
xunjieli11834f02015-12-22 04:27:081414 };
1415
1416 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:131417 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151418 spdy_util_.ConstructSpdyGetReply(kExtraHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081419
1420 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411421 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3),
xunjieli11834f02015-12-22 04:27:081422 };
1423
Ryan Sleevib8d7ea02018-05-07 20:01:011424 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081425
Tsuyoshi Horof8861cb2022-07-05 23:50:201426 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081427 request_info->method = "POST";
bnc3d9035b32016-06-30 18:18:481428 request_info->url = default_url_;
Brett Wilson5accd242017-11-30 22:07:321429 request_info->extra_headers.SetHeader(
1430 net::HttpRequestHeaders::kContentLength,
1431 base::NumberToString(kBodyDataSize * 3));
xunjieli11834f02015-12-22 04:27:081432
Victor Costan9c7302b2018-08-27 16:39:441433 scoped_refptr<IOBuffer> read_buffer =
1434 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201435 auto delegate =
1436 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
xunjieli11834f02015-12-22 04:27:081437 delegate->SetRunUntilCompletion(true);
1438 delegate->Start(std::move(request_info), http_session_.get());
1439
1440 base::RunLoop().RunUntilIdle();
Bence Békyd0d69502019-06-25 19:47:181441 EXPECT_THAT(delegate->error(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
xunjieli11834f02015-12-22 04:27:081442 EXPECT_EQ(delegate->response_headers().end(),
1443 delegate->response_headers().find(":status"));
1444 EXPECT_EQ(0, delegate->on_data_read_count());
1445 EXPECT_EQ(0, delegate->on_data_sent_count());
1446 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1447 // BidirectionalStreamSpdyStreamJob does not count the bytes sent for |rst|
1448 // because it is sent after SpdyStream::Delegate::OnClose is called.
Ryan Sleevib8d7ea02018-05-07 20:01:011449 EXPECT_EQ(CountWriteBytes(base::make_span(writes, 1)),
1450 delegate->GetTotalSentBytes());
Minjeong Leebbd225772017-11-28 14:37:251451 EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
xunjieli2704f5d2016-06-10 16:02:231452
Matt Reichhoff0049a0b72021-10-20 20:44:261453 auto entries = net_log_observer_.GetEntries();
xunjieli2704f5d2016-06-10 16:02:231454
1455 size_t index = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001456 entries, 0, NetLogEventType::BIDIRECTIONAL_STREAM_READY,
1457 NetLogEventPhase::NONE);
xunjieli2704f5d2016-06-10 16:02:231458 EXPECT_TRUE(
Eric Roman79cc7552019-07-19 02:17:541459 GetBooleanValueFromParams(entries[index], "request_headers_sent"));
xunjieli2704f5d2016-06-10 16:02:231460
mikecirone8b85c432016-09-08 19:11:001461 index = ExpectLogContainsSomewhere(
1462 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_FAILED,
1463 NetLogEventPhase::NONE);
Eric Roman79cc7552019-07-19 02:17:541464 EXPECT_EQ(ERR_HTTP2_PROTOCOL_ERROR,
1465 GetNetErrorCodeFromParams(entries[index]));
xunjieli11834f02015-12-22 04:27:081466}
1467
xunjieli9ff75c562016-08-10 20:26:161468TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnHeadersReceived) {
Ryan Hamilton0239aac2018-05-19 00:03:131469 spdy::SpdySerializedFrame req(
1470 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
xunjieli11834f02015-12-22 04:27:081471
Ryan Hamilton0239aac2018-05-19 00:03:131472 spdy::SpdySerializedFrame rst(
1473 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
xunjieli11834f02015-12-22 04:27:081474 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411475 CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
xunjieli11834f02015-12-22 04:27:081476 };
1477
1478 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
Ryan Hamilton0239aac2018-05-19 00:03:131479 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151480 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081481
1482 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411483 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3),
xunjieli11834f02015-12-22 04:27:081484 };
1485
Ryan Sleevib8d7ea02018-05-07 20:01:011486 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081487
Tsuyoshi Horof8861cb2022-07-05 23:50:201488 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081489 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481490 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081491 request_info->priority = LOWEST;
1492 request_info->end_stream_on_headers = true;
1493
Victor Costan9c7302b2018-08-27 16:39:441494 scoped_refptr<IOBuffer> read_buffer =
1495 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201496 auto delegate = std::make_unique<DeleteStreamDelegate>(
xunjieli9ff75c562016-08-10 20:26:161497 read_buffer.get(), kReadBufferSize,
Tsuyoshi Horof8861cb2022-07-05 23:50:201498 DeleteStreamDelegate::Phase::ON_HEADERS_RECEIVED);
xunjieli11834f02015-12-22 04:27:081499 delegate->SetRunUntilCompletion(true);
1500 delegate->Start(std::move(request_info), http_session_.get());
1501 // Makes sure delegate does not get called.
1502 base::RunLoop().RunUntilIdle();
Bence Béky4c325e52020-10-22 20:48:011503 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjieli11834f02015-12-22 04:27:081504 EXPECT_EQ("200", response_headers.find(":status")->second);
1505 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1506 EXPECT_EQ(0u, delegate->data_received().size());
1507 EXPECT_EQ(0, delegate->on_data_sent_count());
1508 EXPECT_EQ(0, delegate->on_data_read_count());
1509
xunjieli9ff75c562016-08-10 20:26:161510 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1511 // Bytes sent excludes the RST frame.
Ryan Sleevib8d7ea02018-05-07 20:01:011512 EXPECT_EQ(
Daniel Cheng5feb16f2022-02-28 06:52:071513 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
Ryan Sleevib8d7ea02018-05-07 20:01:011514 delegate->GetTotalSentBytes());
1515 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081516}
1517
xunjieli9ff75c562016-08-10 20:26:161518TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnDataRead) {
Ryan Hamilton0239aac2018-05-19 00:03:131519 spdy::SpdySerializedFrame req(
1520 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
xunjieli11834f02015-12-22 04:27:081521
Ryan Hamilton0239aac2018-05-19 00:03:131522 spdy::SpdySerializedFrame rst(
1523 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
xunjieli11834f02015-12-22 04:27:081524 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411525 CreateMockWrite(req, 0), CreateMockWrite(rst, 3),
xunjieli11834f02015-12-22 04:27:081526 };
1527
1528 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
Ryan Hamilton0239aac2018-05-19 00:03:131529 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151530 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081531
Ryan Hamilton0239aac2018-05-19 00:03:131532 spdy::SpdySerializedFrame response_body_frame(
bncdf80d44fd2016-07-15 20:27:411533 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjieli11834f02015-12-22 04:27:081534
1535 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411536 CreateMockRead(resp, 1), CreateMockRead(response_body_frame, 2),
xunjieli11834f02015-12-22 04:27:081537 MockRead(ASYNC, 0, 4),
1538 };
1539
Ryan Sleevib8d7ea02018-05-07 20:01:011540 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081541
Tsuyoshi Horof8861cb2022-07-05 23:50:201542 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081543 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481544 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081545 request_info->priority = LOWEST;
1546 request_info->end_stream_on_headers = true;
1547
Victor Costan9c7302b2018-08-27 16:39:441548 scoped_refptr<IOBuffer> read_buffer =
1549 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201550 auto delegate = std::make_unique<DeleteStreamDelegate>(
1551 read_buffer.get(), kReadBufferSize,
1552 DeleteStreamDelegate::Phase::ON_DATA_READ);
xunjieli11834f02015-12-22 04:27:081553 delegate->SetRunUntilCompletion(true);
1554 delegate->Start(std::move(request_info), http_session_.get());
1555 // Makes sure delegate does not get called.
1556 base::RunLoop().RunUntilIdle();
Bence Béky4c325e52020-10-22 20:48:011557 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjieli11834f02015-12-22 04:27:081558 EXPECT_EQ("200", response_headers.find(":status")->second);
1559 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1560 EXPECT_EQ(kUploadDataSize * 1,
1561 static_cast<int>(delegate->data_received().size()));
1562 EXPECT_EQ(0, delegate->on_data_sent_count());
1563
xunjieli9ff75c562016-08-10 20:26:161564 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1565 // Bytes sent excludes the RST frame.
Ryan Sleevib8d7ea02018-05-07 20:01:011566 EXPECT_EQ(
Daniel Cheng5feb16f2022-02-28 06:52:071567 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
Ryan Sleevib8d7ea02018-05-07 20:01:011568 delegate->GetTotalSentBytes());
1569 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081570}
1571
xunjieli9ff75c562016-08-10 20:26:161572TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnTrailersReceived) {
Ryan Hamilton0239aac2018-05-19 00:03:131573 spdy::SpdySerializedFrame req(
1574 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
xunjieli11834f02015-12-22 04:27:081575
Ryan Hamilton0239aac2018-05-19 00:03:131576 spdy::SpdySerializedFrame rst(
1577 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
xunjieli11834f02015-12-22 04:27:081578 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411579 CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
xunjieli11834f02015-12-22 04:27:081580 };
1581
1582 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
Ryan Hamilton0239aac2018-05-19 00:03:131583 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151584 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081585
Ryan Hamilton0239aac2018-05-19 00:03:131586 spdy::SpdySerializedFrame response_body_frame(
bncdf80d44fd2016-07-15 20:27:411587 spdy_util_.ConstructSpdyDataFrame(1, false));
xunjieli11834f02015-12-22 04:27:081588
Bence Béky4c325e52020-10-22 20:48:011589 spdy::Http2HeaderBlock trailers;
xunjielid4c21ab2016-04-28 22:44:471590 trailers["foo"] = "bar";
Ryan Hamilton0239aac2018-05-19 00:03:131591 spdy::SpdySerializedFrame response_trailers(
bnc086b39e12016-06-24 13:05:261592 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers), true));
xunjieli11834f02015-12-22 04:27:081593
1594 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411595 CreateMockRead(resp, 1), CreateMockRead(response_body_frame, 2),
1596 CreateMockRead(response_trailers, 3), MockRead(ASYNC, 0, 5),
xunjieli11834f02015-12-22 04:27:081597 };
1598
Ryan Sleevib8d7ea02018-05-07 20:01:011599 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081600
Tsuyoshi Horof8861cb2022-07-05 23:50:201601 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081602 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481603 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081604 request_info->priority = LOWEST;
1605 request_info->end_stream_on_headers = true;
1606
Victor Costan9c7302b2018-08-27 16:39:441607 scoped_refptr<IOBuffer> read_buffer =
1608 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201609 auto delegate = std::make_unique<DeleteStreamDelegate>(
xunjieli9ff75c562016-08-10 20:26:161610 read_buffer.get(), kReadBufferSize,
Tsuyoshi Horof8861cb2022-07-05 23:50:201611 DeleteStreamDelegate::Phase::ON_TRAILERS_RECEIVED);
xunjieli11834f02015-12-22 04:27:081612 delegate->SetRunUntilCompletion(true);
1613 delegate->Start(std::move(request_info), http_session_.get());
1614 // Makes sure delegate does not get called.
1615 base::RunLoop().RunUntilIdle();
Bence Béky4c325e52020-10-22 20:48:011616 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjieli11834f02015-12-22 04:27:081617 EXPECT_EQ("200", response_headers.find(":status")->second);
1618 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1619 EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
1620 EXPECT_EQ(0, delegate->on_data_sent_count());
1621 // OnDataRead may or may not have been fired before the stream is
xunjieli9ff75c562016-08-10 20:26:161622 // deleted.
1623 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1624 // Bytes sent excludes the RST frame.
Ryan Sleevib8d7ea02018-05-07 20:01:011625 EXPECT_EQ(
Daniel Cheng5feb16f2022-02-28 06:52:071626 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
Ryan Sleevib8d7ea02018-05-07 20:01:011627 delegate->GetTotalSentBytes());
1628 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081629}
1630
xunjieli9ff75c562016-08-10 20:26:161631TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnFailed) {
Ryan Hamilton0239aac2018-05-19 00:03:131632 spdy::SpdySerializedFrame req(
1633 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
xunjieli11834f02015-12-22 04:27:081634
Ryan Hamilton0239aac2018-05-19 00:03:131635 spdy::SpdySerializedFrame rst(
1636 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
xunjieli11834f02015-12-22 04:27:081637
1638 MockWrite writes[] = {
bncdf80d44fd2016-07-15 20:27:411639 CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
xunjieli11834f02015-12-22 04:27:081640 };
1641
1642 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
Ryan Hamilton0239aac2018-05-19 00:03:131643 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151644 spdy_util_.ConstructSpdyGetReply(kExtraHeaders, 1, 1));
xunjieli11834f02015-12-22 04:27:081645
1646 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411647 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3),
xunjieli11834f02015-12-22 04:27:081648 };
1649
Ryan Sleevib8d7ea02018-05-07 20:01:011650 InitSession(reads, writes, SocketTag());
xunjieli11834f02015-12-22 04:27:081651
Tsuyoshi Horof8861cb2022-07-05 23:50:201652 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjieli11834f02015-12-22 04:27:081653 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481654 request_info->url = default_url_;
xunjieli11834f02015-12-22 04:27:081655 request_info->priority = LOWEST;
1656 request_info->end_stream_on_headers = true;
1657
Victor Costan9c7302b2018-08-27 16:39:441658 scoped_refptr<IOBuffer> read_buffer =
1659 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201660 auto delegate = std::make_unique<DeleteStreamDelegate>(
1661 read_buffer.get(), kReadBufferSize,
1662 DeleteStreamDelegate::Phase::ON_FAILED);
xunjieli11834f02015-12-22 04:27:081663 delegate->SetRunUntilCompletion(true);
1664 delegate->Start(std::move(request_info), http_session_.get());
1665 // Makes sure delegate does not get called.
1666 base::RunLoop().RunUntilIdle();
1667 EXPECT_EQ(delegate->response_headers().end(),
1668 delegate->response_headers().find(":status"));
1669 EXPECT_EQ(0, delegate->on_data_sent_count());
1670 EXPECT_EQ(0, delegate->on_data_read_count());
Bence Békyd0d69502019-06-25 19:47:181671 EXPECT_THAT(delegate->error(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
xunjieli11834f02015-12-22 04:27:081672
xunjieli9ff75c562016-08-10 20:26:161673 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1674 // Bytes sent excludes the RST frame.
Ryan Sleevib8d7ea02018-05-07 20:01:011675 EXPECT_EQ(
Daniel Cheng5feb16f2022-02-28 06:52:071676 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
Ryan Sleevib8d7ea02018-05-07 20:01:011677 delegate->GetTotalSentBytes());
Minjeong Leebbd225772017-11-28 14:37:251678 EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
xunjieli11834f02015-12-22 04:27:081679}
1680
xunjielib3a648e2016-03-22 03:39:511681TEST_F(BidirectionalStreamTest, TestHonorAlternativeServiceHeader) {
Ryan Hamilton0239aac2018-05-19 00:03:131682 spdy::SpdySerializedFrame req(
1683 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:411684 MockWrite writes[] = {CreateMockWrite(req, 0)};
xunjielib3a648e2016-03-22 03:39:511685
Ryan Hamiltona2dcbae2022-02-09 19:02:451686 std::string alt_svc_header_value =
1687 quic::AlpnForVersion(DefaultSupportedQuicVersions().front());
xunjielib3a648e2016-03-22 03:39:511688 alt_svc_header_value.append("=\"www.example.org:443\"");
1689 const char* const kExtraResponseHeaders[] = {"alt-svc",
1690 alt_svc_header_value.c_str()};
Ryan Hamilton0239aac2018-05-19 00:03:131691 spdy::SpdySerializedFrame resp(
bnc42331402016-07-25 13:36:151692 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131693 spdy::SpdySerializedFrame body_frame(
1694 spdy_util_.ConstructSpdyDataFrame(1, true));
xunjielib3a648e2016-03-22 03:39:511695
1696 MockRead reads[] = {
bncdf80d44fd2016-07-15 20:27:411697 CreateMockRead(resp, 1), CreateMockRead(body_frame, 2),
xunjielib3a648e2016-03-22 03:39:511698 MockRead(SYNCHRONOUS, 0, 3),
1699 };
1700
xunjielib3a648e2016-03-22 03:39:511701 // Enable QUIC so that the alternative service header can be added to
1702 // HttpServerProperties.
1703 session_deps_.enable_quic = true;
Ryan Sleevib8d7ea02018-05-07 20:01:011704 InitSession(reads, writes, SocketTag());
xunjielib3a648e2016-03-22 03:39:511705
Tsuyoshi Horof8861cb2022-07-05 23:50:201706 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
xunjielib3a648e2016-03-22 03:39:511707 request_info->method = "GET";
bnc3d9035b32016-06-30 18:18:481708 request_info->url = default_url_;
xunjielib3a648e2016-03-22 03:39:511709 request_info->priority = LOWEST;
1710 request_info->end_stream_on_headers = true;
1711
Victor Costan9c7302b2018-08-27 16:39:441712 scoped_refptr<IOBuffer> read_buffer =
1713 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horoc39623a82022-07-11 01:27:581714 auto timer = std::make_unique<MockTimer>();
Tsuyoshi Horof8861cb2022-07-05 23:50:201715 auto delegate = std::make_unique<TestDelegateBase>(
Tsuyoshi Horoc39623a82022-07-11 01:27:581716 read_buffer.get(), kReadBufferSize, std::move(timer));
xunjielib3a648e2016-03-22 03:39:511717 delegate->SetRunUntilCompletion(true);
1718 delegate->Start(std::move(request_info), http_session_.get());
1719
Bence Béky4c325e52020-10-22 20:48:011720 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
xunjielib3a648e2016-03-22 03:39:511721 EXPECT_EQ("200", response_headers.find(":status")->second);
1722 EXPECT_EQ(alt_svc_header_value, response_headers.find("alt-svc")->second);
1723 EXPECT_EQ(0, delegate->on_data_sent_count());
1724 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1725 EXPECT_EQ(kUploadData, delegate->data_received());
Ryan Sleevib8d7ea02018-05-07 20:01:011726 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1727 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
xunjielib3a648e2016-03-22 03:39:511728
zhongyic4de03032017-05-19 04:07:341729 AlternativeServiceInfoVector alternative_service_info_vector =
1730 http_session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:491731 url::SchemeHostPort(default_url_), NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:341732 ASSERT_EQ(1u, alternative_service_info_vector.size());
1733 AlternativeService alternative_service(kProtoQUIC, "www.example.org", 443);
1734 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:541735 alternative_service_info_vector[0].alternative_service());
xunjielib3a648e2016-03-22 03:39:511736}
1737
Paul Jensen76bfe082018-02-23 03:36:051738// Test that a BidirectionalStream created with a specific tag, tags the
1739// underlying socket appropriately.
1740TEST_F(BidirectionalStreamTest, Tagging) {
Ryan Hamilton0239aac2018-05-19 00:03:131741 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
Paul Jensen76bfe082018-02-23 03:36:051742 kDefaultUrl, 1, kBodyDataSize, LOW, nullptr, 0));
Ryan Hamilton0239aac2018-05-19 00:03:131743 spdy::SpdySerializedFrame data_frame(
Paul Jensen76bfe082018-02-23 03:36:051744 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
1745 MockWrite writes[] = {
1746 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
1747 };
Ryan Hamilton0239aac2018-05-19 00:03:131748 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1749 spdy::SpdySerializedFrame response_body_frame(
Paul Jensen76bfe082018-02-23 03:36:051750 spdy_util_.ConstructSpdyDataFrame(1, /*fin=*/true));
1751 MockRead reads[] = {
1752 CreateMockRead(resp, 1),
1753 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
1754 CreateMockRead(response_body_frame, 4), MockRead(ASYNC, 0, 5),
1755 };
Xiaohan Wang2a6845b2022-01-08 04:40:571756#if BUILDFLAG(IS_ANDROID)
Paul Jensen76bfe082018-02-23 03:36:051757 SocketTag tag(0x12345678, 0x87654321);
1758#else
1759 SocketTag tag;
1760#endif
Ryan Sleevib8d7ea02018-05-07 20:01:011761 InitSession(reads, writes, tag);
Paul Jensen76bfe082018-02-23 03:36:051762
Tsuyoshi Horof8861cb2022-07-05 23:50:201763 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
Paul Jensen76bfe082018-02-23 03:36:051764 request_info->method = "POST";
1765 request_info->url = default_url_;
1766 request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
1767 base::NumberToString(kBodyDataSize));
1768 request_info->socket_tag = tag;
Victor Costan9c7302b2018-08-27 16:39:441769 scoped_refptr<IOBuffer> read_buffer =
1770 base::MakeRefCounted<IOBuffer>(kReadBufferSize);
Tsuyoshi Horof8861cb2022-07-05 23:50:201771 auto delegate =
1772 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
Paul Jensen76bfe082018-02-23 03:36:051773 delegate->Start(std::move(request_info), http_session_.get());
1774 sequenced_data_->RunUntilPaused();
1775
1776 EXPECT_EQ(socket_factory_->GetLastProducedTCPSocket()->tag(), tag);
1777 EXPECT_TRUE(
1778 socket_factory_->GetLastProducedTCPSocket()->tagged_before_connected());
1779 void* socket = socket_factory_->GetLastProducedTCPSocket();
1780
Victor Costan9c7302b2018-08-27 16:39:441781 scoped_refptr<StringIOBuffer> buf =
1782 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
Paul Jensen76bfe082018-02-23 03:36:051783 delegate->SendData(buf.get(), buf->size(), true);
1784 sequenced_data_->Resume();
1785 base::RunLoop().RunUntilIdle();
1786
1787 EXPECT_EQ(socket, socket_factory_->GetLastProducedTCPSocket());
1788}
1789
xunjieli11834f02015-12-22 04:27:081790} // namespace net