1 // Copyright 2015 The Chromium Authors
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
7 #include <memory>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "base/containers/span.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/time/time.h"
18 #include "base/timer/mock_timer.h"
19 #include "base/timer/timer.h"
20 #include "build/build_config.h"
21 #include "net/base/completion_once_callback.h"
22 #include "net/base/load_timing_info.h"
23 #include "net/base/load_timing_info_test_util.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/session_usage.h"
26 #include "net/dns/public/secure_dns_policy.h"
27 #include "net/http/bidirectional_stream_request_info.h"
28 #include "net/http/http_network_session.h"
29 #include "net/http/http_response_headers.h"
30 #include "net/http/http_server_properties.h"
31 #include "net/log/net_log.h"
32 #include "net/log/net_log_capture_mode.h"
33 #include "net/log/net_log_event_type.h"
34 #include "net/log/net_log_source_type.h"
35 #include "net/log/test_net_log.h"
36 #include "net/log/test_net_log_util.h"
37 #include "net/socket/socket_tag.h"
38 #include "net/socket/socket_test_util.h"
39 #include "net/spdy/spdy_session.h"
40 #include "net/spdy/spdy_test_util_common.h"
41 #include "net/ssl/ssl_cert_request_info.h"
42 #include "net/test/cert_test_util.h"
43 #include "net/test/gtest_util.h"
44 #include "net/test/test_data_directory.h"
45 #include "net/test/test_with_task_environment.h"
46 #include "net/url_request/url_request_test_util.h"
47 #include "testing/gmock/include/gmock/gmock.h"
48 #include "testing/gtest/include/gtest/gtest.h"
49
50 using net::test::IsError;
51 using net::test::IsOk;
52
53 namespace net {
54
55 namespace {
56
57 const char kBodyData[] = "Body data";
58 const size_t kBodyDataSize = std::size(kBodyData);
59 const std::string kBodyDataString(kBodyData, kBodyDataSize);
60 // Size of the buffer to be allocated for each read.
61 const size_t kReadBufferSize = 4096;
62
63 // Expects that fields of |load_timing_info| are valid time stamps.
ExpectLoadTimingValid(const LoadTimingInfo & load_timing_info)64 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info) {
65 EXPECT_FALSE(load_timing_info.request_start.is_null());
66 EXPECT_FALSE(load_timing_info.request_start_time.is_null());
67 EXPECT_FALSE(load_timing_info.receive_headers_end.is_null());
68 EXPECT_FALSE(load_timing_info.send_start.is_null());
69 EXPECT_FALSE(load_timing_info.send_end.is_null());
70 EXPECT_TRUE(load_timing_info.request_start <=
71 load_timing_info.receive_headers_end);
72 EXPECT_TRUE(load_timing_info.send_start <= load_timing_info.send_end);
73 }
74
75 // Tests the load timing of a stream that's connected and is not the first
76 // request sent on a connection.
TestLoadTimingReused(const LoadTimingInfo & load_timing_info)77 void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
78 EXPECT_TRUE(load_timing_info.socket_reused);
79
80 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
81 ExpectLoadTimingValid(load_timing_info);
82 }
83
84 // Tests the load timing of a stream that's connected and using a fresh
85 // connection.
TestLoadTimingNotReused(const LoadTimingInfo & load_timing_info)86 void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info) {
87 EXPECT_FALSE(load_timing_info.socket_reused);
88
89 ExpectConnectTimingHasTimes(
90 load_timing_info.connect_timing,
91 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
92 ExpectLoadTimingValid(load_timing_info);
93 }
94
95 // Delegate that reads data but does not send any data.
96 class TestDelegateBase : public BidirectionalStream::Delegate {
97 public:
TestDelegateBase(IOBuffer * read_buf,int read_buf_len)98 TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
99 : TestDelegateBase(read_buf,
100 read_buf_len,
101 std::make_unique<base::OneShotTimer>()) {}
102
TestDelegateBase(IOBuffer * read_buf,int read_buf_len,std::unique_ptr<base::OneShotTimer> timer)103 TestDelegateBase(IOBuffer* read_buf,
104 int read_buf_len,
105 std::unique_ptr<base::OneShotTimer> timer)
106 : read_buf_(read_buf),
107 read_buf_len_(read_buf_len),
108 timer_(std::move(timer)) {}
109
110 TestDelegateBase(const TestDelegateBase&) = delete;
111 TestDelegateBase& operator=(const TestDelegateBase&) = delete;
112
113 ~TestDelegateBase() override = default;
114
OnStreamReady(bool request_headers_sent)115 void OnStreamReady(bool request_headers_sent) override {
116 // Request headers should always be sent in H2's case, because the
117 // functionality to combine header frame with data frames is not
118 // implemented.
119 EXPECT_TRUE(request_headers_sent);
120 if (callback_.is_null())
121 return;
122 std::move(callback_).Run(OK);
123 }
124
OnHeadersReceived(const spdy::Http2HeaderBlock & response_headers)125 void OnHeadersReceived(
126 const spdy::Http2HeaderBlock& response_headers) override {
127 CHECK(!not_expect_callback_);
128
129 response_headers_ = response_headers.Clone();
130
131 if (!do_not_start_read_)
132 StartOrContinueReading();
133 }
134
OnDataRead(int bytes_read)135 void OnDataRead(int bytes_read) override {
136 CHECK(!not_expect_callback_);
137
138 ++on_data_read_count_;
139 CHECK_GE(bytes_read, OK);
140 data_received_.append(read_buf_->data(), bytes_read);
141 if (!do_not_start_read_)
142 StartOrContinueReading();
143 }
144
OnDataSent()145 void OnDataSent() override {
146 CHECK(!not_expect_callback_);
147
148 ++on_data_sent_count_;
149 }
150
OnTrailersReceived(const spdy::Http2HeaderBlock & trailers)151 void OnTrailersReceived(const spdy::Http2HeaderBlock& trailers) override {
152 CHECK(!not_expect_callback_);
153
154 trailers_ = trailers.Clone();
155 if (run_until_completion_)
156 loop_->Quit();
157 }
158
OnFailed(int error)159 void OnFailed(int error) override {
160 CHECK(!not_expect_callback_);
161 CHECK_EQ(OK, error_);
162 CHECK_NE(OK, error);
163
164 error_ = error;
165 if (run_until_completion_)
166 loop_->Quit();
167 }
168
Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,HttpNetworkSession * session)169 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
170 HttpNetworkSession* session) {
171 stream_ = std::make_unique<BidirectionalStream>(
172 std::move(request_info), session, true, this, std::move(timer_));
173 if (run_until_completion_)
174 loop_->Run();
175 }
176
Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,HttpNetworkSession * session,CompletionOnceCallback cb)177 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
178 HttpNetworkSession* session,
179 CompletionOnceCallback cb) {
180 callback_ = std::move(cb);
181 stream_ = std::make_unique<BidirectionalStream>(
182 std::move(request_info), session, true, this, std::move(timer_));
183 if (run_until_completion_)
184 WaitUntilCompletion();
185 }
186
WaitUntilCompletion()187 void WaitUntilCompletion() { loop_->Run(); }
188
SendData(const scoped_refptr<IOBuffer> & data,int length,bool end_of_stream)189 void SendData(const scoped_refptr<IOBuffer>& data,
190 int length,
191 bool end_of_stream) {
192 SendvData({data}, {length}, end_of_stream);
193 }
194
SendvData(const std::vector<scoped_refptr<IOBuffer>> & data,const std::vector<int> & length,bool end_of_stream)195 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& data,
196 const std::vector<int>& length,
197 bool end_of_stream) {
198 not_expect_callback_ = true;
199 stream_->SendvData(data, length, end_of_stream);
200 not_expect_callback_ = false;
201 }
202
203 // Starts or continues reading data from |stream_| until no more bytes
204 // can be read synchronously.
StartOrContinueReading()205 void StartOrContinueReading() {
206 int rv = ReadData();
207 while (rv > 0) {
208 rv = ReadData();
209 }
210 if (run_until_completion_ && rv == 0)
211 loop_->Quit();
212 }
213
214 // Calls ReadData on the |stream_| and updates internal states.
ReadData()215 int ReadData() {
216 not_expect_callback_ = true;
217 int rv = stream_->ReadData(read_buf_.get(), read_buf_len_);
218 not_expect_callback_ = false;
219 if (rv > 0)
220 data_received_.append(read_buf_->data(), rv);
221 return rv;
222 }
223
224 // Deletes |stream_|.
DeleteStream()225 void DeleteStream() {
226 next_proto_ = stream_->GetProtocol();
227 received_bytes_ = stream_->GetTotalReceivedBytes();
228 sent_bytes_ = stream_->GetTotalSentBytes();
229 stream_->GetLoadTimingInfo(&load_timing_info_);
230 stream_.reset();
231 }
232
GetProtocol() const233 NextProto GetProtocol() const {
234 if (stream_)
235 return stream_->GetProtocol();
236 return next_proto_;
237 }
238
GetTotalReceivedBytes() const239 int64_t GetTotalReceivedBytes() const {
240 if (stream_)
241 return stream_->GetTotalReceivedBytes();
242 return received_bytes_;
243 }
244
GetTotalSentBytes() const245 int64_t GetTotalSentBytes() const {
246 if (stream_)
247 return stream_->GetTotalSentBytes();
248 return sent_bytes_;
249 }
250
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const251 void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
252 if (stream_) {
253 stream_->GetLoadTimingInfo(load_timing_info);
254 return;
255 }
256 *load_timing_info = load_timing_info_;
257 }
258
259 // Const getters for internal states.
data_received() const260 const std::string& data_received() const { return data_received_; }
error() const261 int error() const { return error_; }
response_headers() const262 const spdy::Http2HeaderBlock& response_headers() const {
263 return response_headers_;
264 }
trailers() const265 const spdy::Http2HeaderBlock& trailers() const { return trailers_; }
on_data_read_count() const266 int on_data_read_count() const { return on_data_read_count_; }
on_data_sent_count() const267 int on_data_sent_count() const { return on_data_sent_count_; }
268
269 // Sets whether the delegate should automatically start reading.
set_do_not_start_read(bool do_not_start_read)270 void set_do_not_start_read(bool do_not_start_read) {
271 do_not_start_read_ = do_not_start_read;
272 }
273 // Sets whether the delegate should wait until the completion of the stream.
SetRunUntilCompletion(bool run_until_completion)274 void SetRunUntilCompletion(bool run_until_completion) {
275 run_until_completion_ = run_until_completion;
276 loop_ = std::make_unique<base::RunLoop>();
277 }
278
279 protected:
280 // Quits |loop_|.
QuitLoop()281 void QuitLoop() { loop_->Quit(); }
282
283 private:
284 std::unique_ptr<BidirectionalStream> stream_;
285 scoped_refptr<IOBuffer> read_buf_;
286 int read_buf_len_;
287 std::unique_ptr<base::OneShotTimer> timer_;
288 std::string data_received_;
289 std::unique_ptr<base::RunLoop> loop_;
290 spdy::Http2HeaderBlock response_headers_;
291 spdy::Http2HeaderBlock trailers_;
292 NextProto next_proto_;
293 int64_t received_bytes_ = 0;
294 int64_t sent_bytes_ = 0;
295 LoadTimingInfo load_timing_info_;
296 int error_ = OK;
297 int on_data_read_count_ = 0;
298 int on_data_sent_count_ = 0;
299 bool do_not_start_read_ = false;
300 bool run_until_completion_ = false;
301 // This is to ensure that delegate callback is not invoked synchronously when
302 // calling into |stream_|.
303 bool not_expect_callback_ = false;
304
305 CompletionOnceCallback callback_;
306 };
307
308 // A delegate that deletes the stream in a particular callback.
309 class DeleteStreamDelegate : public TestDelegateBase {
310 public:
311 // Specifies in which callback the stream can be deleted.
312 enum Phase {
313 ON_HEADERS_RECEIVED,
314 ON_DATA_READ,
315 ON_TRAILERS_RECEIVED,
316 ON_FAILED,
317 };
318
DeleteStreamDelegate(IOBuffer * buf,int buf_len,Phase phase)319 DeleteStreamDelegate(IOBuffer* buf, int buf_len, Phase phase)
320 : TestDelegateBase(buf, buf_len), phase_(phase) {}
321
322 DeleteStreamDelegate(const DeleteStreamDelegate&) = delete;
323 DeleteStreamDelegate& operator=(const DeleteStreamDelegate&) = delete;
324
325 ~DeleteStreamDelegate() override = default;
326
OnHeadersReceived(const spdy::Http2HeaderBlock & response_headers)327 void OnHeadersReceived(
328 const spdy::Http2HeaderBlock& response_headers) override {
329 TestDelegateBase::OnHeadersReceived(response_headers);
330 if (phase_ == ON_HEADERS_RECEIVED) {
331 DeleteStream();
332 QuitLoop();
333 }
334 }
335
OnDataSent()336 void OnDataSent() override { NOTREACHED(); }
337
OnDataRead(int bytes_read)338 void OnDataRead(int bytes_read) override {
339 if (phase_ == ON_HEADERS_RECEIVED) {
340 NOTREACHED();
341 return;
342 }
343 TestDelegateBase::OnDataRead(bytes_read);
344 if (phase_ == ON_DATA_READ) {
345 DeleteStream();
346 QuitLoop();
347 }
348 }
349
OnTrailersReceived(const spdy::Http2HeaderBlock & trailers)350 void OnTrailersReceived(const spdy::Http2HeaderBlock& trailers) override {
351 if (phase_ == ON_HEADERS_RECEIVED || phase_ == ON_DATA_READ) {
352 NOTREACHED();
353 return;
354 }
355 TestDelegateBase::OnTrailersReceived(trailers);
356 if (phase_ == ON_TRAILERS_RECEIVED) {
357 DeleteStream();
358 QuitLoop();
359 }
360 }
361
OnFailed(int error)362 void OnFailed(int error) override {
363 if (phase_ != ON_FAILED) {
364 NOTREACHED();
365 return;
366 }
367 TestDelegateBase::OnFailed(error);
368 DeleteStream();
369 QuitLoop();
370 }
371
372 private:
373 // Indicates in which callback the delegate should cancel or delete the
374 // stream.
375 Phase phase_;
376 };
377
378 // A Timer that does not start a delayed task unless the timer is fired.
379 class MockTimer : public base::MockOneShotTimer {
380 public:
381 MockTimer() = default;
382
383 MockTimer(const MockTimer&) = delete;
384 MockTimer& operator=(const MockTimer&) = delete;
385
386 ~MockTimer() override = default;
387
Start(const base::Location & posted_from,base::TimeDelta delay,base::OnceClosure user_task)388 void Start(const base::Location& posted_from,
389 base::TimeDelta delay,
390 base::OnceClosure user_task) override {
391 // Sets a maximum delay, so the timer does not fire unless it is told to.
392 base::TimeDelta infinite_delay = base::TimeDelta::Max();
393 base::MockOneShotTimer::Start(posted_from, infinite_delay,
394 std::move(user_task));
395 }
396 };
397
398 } // namespace
399
400 class BidirectionalStreamTest : public TestWithTaskEnvironment {
401 public:
BidirectionalStreamTest()402 BidirectionalStreamTest()
403 : default_url_(kDefaultUrl),
404 host_port_pair_(HostPortPair::FromURL(default_url_)),
405 ssl_data_(SSLSocketDataProvider(ASYNC, OK)) {
406 ssl_data_.next_proto = kProtoHTTP2;
407 ssl_data_.ssl_info.cert =
408 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
409 net_log_observer_.SetObserverCaptureMode(NetLogCaptureMode::kEverything);
410 auto socket_factory = std::make_unique<MockTaggingClientSocketFactory>();
411 socket_factory_ = socket_factory.get();
412 session_deps_.socket_factory = std::move(socket_factory);
413 }
414
415 protected:
TearDown()416 void TearDown() override {
417 if (sequenced_data_) {
418 EXPECT_TRUE(sequenced_data_->AllReadDataConsumed());
419 EXPECT_TRUE(sequenced_data_->AllWriteDataConsumed());
420 }
421 }
422
423 // Initializes the session using SequencedSocketData.
InitSession(base::span<const MockRead> reads,base::span<const MockWrite> writes,const SocketTag & socket_tag)424 void InitSession(base::span<const MockRead> reads,
425 base::span<const MockWrite> writes,
426 const SocketTag& socket_tag) {
427 ASSERT_TRUE(ssl_data_.ssl_info.cert.get());
428 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data_);
429 sequenced_data_ = std::make_unique<SequencedSocketData>(reads, writes);
430 session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get());
431 session_deps_.net_log = NetLog::Get();
432 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
433 SpdySessionKey key(host_port_pair_, PRIVACY_MODE_DISABLED,
434 ProxyChain::Direct(), SessionUsage::kDestination,
435 socket_tag, NetworkAnonymizationKey(),
436 SecureDnsPolicy::kAllow,
437 /*disable_cert_verification_network_fetches=*/false);
438 session_ =
439 CreateSpdySession(http_session_.get(), key,
440 NetLogWithSource::Make(NetLogSourceType::NONE));
441 }
442
443 RecordingNetLogObserver net_log_observer_;
444 SpdyTestUtil spdy_util_;
445 SpdySessionDependencies session_deps_;
446 const GURL default_url_;
447 const HostPortPair host_port_pair_;
448 std::unique_ptr<SequencedSocketData> sequenced_data_;
449 std::unique_ptr<HttpNetworkSession> http_session_;
450 raw_ptr<MockTaggingClientSocketFactory> socket_factory_;
451
452 private:
453 SSLSocketDataProvider ssl_data_;
454 base::WeakPtr<SpdySession> session_;
455 };
456
TEST_F(BidirectionalStreamTest,CreateInsecureStream)457 TEST_F(BidirectionalStreamTest, CreateInsecureStream) {
458 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
459 request_info->method = "GET";
460 request_info->url = GURL("http://www.example.org/");
461
462 TestDelegateBase delegate(nullptr, 0);
463 auto session = std::make_unique<HttpNetworkSession>(
464 SpdySessionDependencies::CreateSessionParams(&session_deps_),
465 SpdySessionDependencies::CreateSessionContext(&session_deps_));
466 delegate.SetRunUntilCompletion(true);
467 delegate.Start(std::move(request_info), session.get());
468
469 EXPECT_THAT(delegate.error(), IsError(ERR_DISALLOWED_URL_SCHEME));
470 }
471
TEST_F(BidirectionalStreamTest,SimplePostRequest)472 TEST_F(BidirectionalStreamTest, SimplePostRequest) {
473 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
474 kDefaultUrl, 1, kBodyDataSize, LOW, nullptr, 0));
475 spdy::SpdySerializedFrame data_frame(
476 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
477 MockWrite writes[] = {
478 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
479 };
480 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
481 spdy::SpdySerializedFrame response_body_frame(
482 spdy_util_.ConstructSpdyDataFrame(1, /*fin=*/true));
483 MockRead reads[] = {
484 CreateMockRead(resp, 1),
485 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
486 CreateMockRead(response_body_frame, 4), MockRead(ASYNC, 0, 5),
487 };
488 InitSession(reads, writes, SocketTag());
489
490 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
491 request_info->method = "POST";
492 request_info->url = default_url_;
493 request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
494 base::NumberToString(kBodyDataSize));
495 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
496 auto delegate =
497 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
498 delegate->Start(std::move(request_info), http_session_.get());
499 sequenced_data_->RunUntilPaused();
500
501 scoped_refptr<StringIOBuffer> buf =
502 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
503 delegate->SendData(buf.get(), buf->size(), true);
504 sequenced_data_->Resume();
505 base::RunLoop().RunUntilIdle();
506 LoadTimingInfo load_timing_info;
507 delegate->GetLoadTimingInfo(&load_timing_info);
508 TestLoadTimingNotReused(load_timing_info);
509
510 EXPECT_EQ(1, delegate->on_data_read_count());
511 EXPECT_EQ(1, delegate->on_data_sent_count());
512 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
513 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
514 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
515 }
516
TEST_F(BidirectionalStreamTest,LoadTimingTwoRequests)517 TEST_F(BidirectionalStreamTest, LoadTimingTwoRequests) {
518 spdy::SpdySerializedFrame req(
519 spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/1, LOW));
520 spdy::SpdySerializedFrame req2(
521 spdy_util_.ConstructSpdyGet(nullptr, 0, /*stream_id=*/3, LOW));
522 MockWrite writes[] = {
523 CreateMockWrite(req, 0), CreateMockWrite(req2, 2),
524 };
525 spdy::SpdySerializedFrame resp(
526 spdy_util_.ConstructSpdyGetReply(nullptr, 0, /*stream_id=*/1));
527 spdy::SpdySerializedFrame resp2(
528 spdy_util_.ConstructSpdyGetReply(nullptr, 0, /*stream_id=*/3));
529 spdy::SpdySerializedFrame resp_body(
530 spdy_util_.ConstructSpdyDataFrame(/*stream_id=*/1, /*fin=*/true));
531 spdy::SpdySerializedFrame resp_body2(
532 spdy_util_.ConstructSpdyDataFrame(/*stream_id=*/3, /*fin=*/true));
533 MockRead reads[] = {CreateMockRead(resp, 1), CreateMockRead(resp_body, 3),
534 CreateMockRead(resp2, 4), CreateMockRead(resp_body2, 5),
535 MockRead(ASYNC, 0, 6)};
536 InitSession(reads, writes, SocketTag());
537
538 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
539 request_info->method = "GET";
540 request_info->url = default_url_;
541 request_info->end_stream_on_headers = true;
542 auto request_info2 = std::make_unique<BidirectionalStreamRequestInfo>();
543 request_info2->method = "GET";
544 request_info2->url = default_url_;
545 request_info2->end_stream_on_headers = true;
546
547 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
548 auto read_buffer2 = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
549 auto delegate =
550 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
551 auto delegate2 =
552 std::make_unique<TestDelegateBase>(read_buffer2.get(), kReadBufferSize);
553 delegate->Start(std::move(request_info), http_session_.get());
554 delegate2->Start(std::move(request_info2), http_session_.get());
555 delegate->SetRunUntilCompletion(true);
556 delegate2->SetRunUntilCompletion(true);
557 base::RunLoop().RunUntilIdle();
558
559 delegate->WaitUntilCompletion();
560 delegate2->WaitUntilCompletion();
561 LoadTimingInfo load_timing_info;
562 delegate->GetLoadTimingInfo(&load_timing_info);
563 TestLoadTimingNotReused(load_timing_info);
564 LoadTimingInfo load_timing_info2;
565 delegate2->GetLoadTimingInfo(&load_timing_info2);
566 TestLoadTimingReused(load_timing_info2);
567 }
568
569 // Creates a BidirectionalStream with an insecure scheme. Destroy the stream
570 // without waiting for the OnFailed task to be executed.
TEST_F(BidirectionalStreamTest,CreateInsecureStreamAndDestroyStreamRightAfter)571 TEST_F(BidirectionalStreamTest,
572 CreateInsecureStreamAndDestroyStreamRightAfter) {
573 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
574 request_info->method = "GET";
575 request_info->url = GURL("http://www.example.org/");
576
577 auto delegate = std::make_unique<TestDelegateBase>(nullptr, 0);
578 auto session = std::make_unique<HttpNetworkSession>(
579 SpdySessionDependencies::CreateSessionParams(&session_deps_),
580 SpdySessionDependencies::CreateSessionContext(&session_deps_));
581 delegate->Start(std::move(request_info), session.get());
582 // Reset stream right before the OnFailed task is executed.
583 delegate.reset();
584
585 base::RunLoop().RunUntilIdle();
586 }
587
TEST_F(BidirectionalStreamTest,ClientAuthRequestIgnored)588 TEST_F(BidirectionalStreamTest, ClientAuthRequestIgnored) {
589 auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
590 cert_request->host_and_port = host_port_pair_;
591
592 // First attempt receives client auth request.
593 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
594 ssl_data1.next_proto = kProtoHTTP2;
595 ssl_data1.cert_request_info = cert_request;
596
597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
598 StaticSocketDataProvider socket_data1;
599 session_deps_.socket_factory->AddSocketDataProvider(&socket_data1);
600
601 // Second attempt succeeds.
602 spdy::SpdySerializedFrame req(
603 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
604 MockWrite writes[] = {
605 CreateMockWrite(req, 0),
606 };
607 spdy::SpdySerializedFrame resp(
608 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
609 spdy::SpdySerializedFrame body_frame(
610 spdy_util_.ConstructSpdyDataFrame(1, true));
611 MockRead reads[] = {
612 CreateMockRead(resp, 1), CreateMockRead(body_frame, 2),
613 MockRead(SYNCHRONOUS, net::OK, 3),
614 };
615
616 SSLSocketDataProvider ssl_data2(ASYNC, OK);
617 ssl_data2.next_proto = kProtoHTTP2;
618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
619 SequencedSocketData socket_data2(reads, writes);
620 session_deps_.socket_factory->AddSocketDataProvider(&socket_data2);
621
622 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
623 SpdySessionKey key(host_port_pair_, PRIVACY_MODE_DISABLED,
624 ProxyChain::Direct(), SessionUsage::kDestination,
625 SocketTag(), NetworkAnonymizationKey(),
626 SecureDnsPolicy::kAllow,
627 /*disable_cert_verification_network_fetches=*/false);
628 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
629 request_info->method = "GET";
630 request_info->url = default_url_;
631 request_info->end_stream_on_headers = true;
632 request_info->priority = LOWEST;
633
634 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
635 auto delegate =
636 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
637
638 delegate->SetRunUntilCompletion(true);
639 delegate->Start(std::move(request_info), http_session_.get());
640
641 // Ensure the certificate was added to the client auth cache.
642 scoped_refptr<X509Certificate> client_cert;
643 scoped_refptr<SSLPrivateKey> client_private_key;
644 ASSERT_TRUE(http_session_->ssl_client_context()->GetClientCertificate(
645 host_port_pair_, &client_cert, &client_private_key));
646 ASSERT_FALSE(client_cert);
647 ASSERT_FALSE(client_private_key);
648
649 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
650 EXPECT_EQ("200", response_headers.find(":status")->second);
651 EXPECT_EQ(1, delegate->on_data_read_count());
652 EXPECT_EQ(0, delegate->on_data_sent_count());
653 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
654 }
655
656 // Simulates user calling ReadData after END_STREAM has been received in
657 // BidirectionalStreamSpdyImpl.
TEST_F(BidirectionalStreamTest,TestReadDataAfterClose)658 TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) {
659 spdy::SpdySerializedFrame req(
660 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
661 MockWrite writes[] = {
662 CreateMockWrite(req, 0),
663 };
664
665 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
666 spdy::SpdySerializedFrame resp(
667 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
668
669 spdy::SpdySerializedFrame body_frame(
670 spdy_util_.ConstructSpdyDataFrame(1, false));
671 // Last body frame has END_STREAM flag set.
672 spdy::SpdySerializedFrame last_body_frame(
673 spdy_util_.ConstructSpdyDataFrame(1, true));
674
675 MockRead reads[] = {
676 CreateMockRead(resp, 1),
677 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
678 CreateMockRead(body_frame, 3),
679 MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
680 CreateMockRead(body_frame, 5),
681 CreateMockRead(last_body_frame, 6),
682 MockRead(SYNCHRONOUS, 0, 7),
683 };
684
685 InitSession(reads, writes, SocketTag());
686
687 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
688 request_info->method = "GET";
689 request_info->url = default_url_;
690 request_info->end_stream_on_headers = true;
691 request_info->priority = LOWEST;
692
693 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
694 // Create a MockTimer. Retain a raw pointer since the underlying
695 // BidirectionalStreamImpl owns it.
696 auto timer = std::make_unique<MockTimer>();
697 MockTimer* timer_ptr = timer.get();
698 auto delegate = std::make_unique<TestDelegateBase>(
699 read_buffer.get(), kReadBufferSize, std::move(timer));
700 delegate->set_do_not_start_read(true);
701
702 delegate->Start(std::move(request_info), http_session_.get());
703
704 // Write request, and deliver response headers.
705 sequenced_data_->RunUntilPaused();
706 EXPECT_FALSE(timer_ptr->IsRunning());
707 // ReadData returns asynchronously because no data is buffered.
708 int rv = delegate->ReadData();
709 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
710 // Deliver a DATA frame.
711 sequenced_data_->Resume();
712 base::RunLoop().RunUntilIdle();
713 timer_ptr->Fire();
714 // Asynchronous completion callback is invoke.
715 EXPECT_EQ(1, delegate->on_data_read_count());
716 EXPECT_EQ(kUploadDataSize * 1,
717 static_cast<int>(delegate->data_received().size()));
718
719 // Deliver the rest. Note that user has not called a second ReadData.
720 sequenced_data_->Resume();
721 base::RunLoop().RunUntilIdle();
722 // ReadData now. Read should complete synchronously.
723 rv = delegate->ReadData();
724 EXPECT_EQ(kUploadDataSize * 2, rv);
725 rv = delegate->ReadData();
726 EXPECT_THAT(rv, IsOk()); // EOF.
727
728 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
729 EXPECT_EQ("200", response_headers.find(":status")->second);
730 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
731 EXPECT_EQ(1, delegate->on_data_read_count());
732 EXPECT_EQ(0, delegate->on_data_sent_count());
733 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
734 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
735 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
736 }
737
738 // Tests that the NetLog contains correct entries.
TEST_F(BidirectionalStreamTest,TestNetLogContainEntries)739 TEST_F(BidirectionalStreamTest, TestNetLogContainEntries) {
740 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
741 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
742 spdy::SpdySerializedFrame data_frame(
743 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
744 MockWrite writes[] = {
745 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
746 };
747
748 spdy::SpdySerializedFrame resp(
749 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
750 spdy::SpdySerializedFrame response_body_frame1(
751 spdy_util_.ConstructSpdyDataFrame(1, false));
752 spdy::SpdySerializedFrame response_body_frame2(
753 spdy_util_.ConstructSpdyDataFrame(1, false));
754
755 spdy::Http2HeaderBlock trailers;
756 trailers["foo"] = "bar";
757 spdy::SpdySerializedFrame response_trailers(
758 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers), true));
759
760 MockRead reads[] = {
761 CreateMockRead(resp, 1),
762 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
763 CreateMockRead(response_body_frame1, 4),
764 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
765 CreateMockRead(response_body_frame2, 6),
766 CreateMockRead(response_trailers, 7),
767 MockRead(ASYNC, 0, 8),
768 };
769
770 InitSession(reads, writes, SocketTag());
771
772 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
773 request_info->method = "POST";
774 request_info->url = default_url_;
775 request_info->priority = LOWEST;
776 request_info->extra_headers.SetHeader(
777 net::HttpRequestHeaders::kContentLength,
778 base::NumberToString(kBodyDataSize * 3));
779
780 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
781 auto timer = std::make_unique<MockTimer>();
782 MockTimer* timer_ptr = timer.get();
783 auto delegate = std::make_unique<TestDelegateBase>(
784 read_buffer.get(), kReadBufferSize, std::move(timer));
785 delegate->set_do_not_start_read(true);
786 delegate->Start(std::move(request_info), http_session_.get());
787 // Send the request and receive response headers.
788 sequenced_data_->RunUntilPaused();
789 EXPECT_FALSE(timer_ptr->IsRunning());
790
791 scoped_refptr<StringIOBuffer> buf =
792 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
793 // Send a DATA frame.
794 delegate->SendData(buf, buf->size(), true);
795 // ReadData returns asynchronously because no data is buffered.
796 int rv = delegate->ReadData();
797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
798 // Deliver the first DATA frame.
799 sequenced_data_->Resume();
800 sequenced_data_->RunUntilPaused();
801 // |sequenced_data_| is now stopped after delivering first DATA frame but
802 // before the second DATA frame.
803 // Fire the timer to allow the first ReadData to complete asynchronously.
804 timer_ptr->Fire();
805 base::RunLoop().RunUntilIdle();
806 EXPECT_EQ(1, delegate->on_data_read_count());
807
808 // Now let |sequenced_data_| run until completion.
809 sequenced_data_->Resume();
810 base::RunLoop().RunUntilIdle();
811 // All data has been delivered, and OnClosed() has been invoked.
812 // Read now, and it should complete synchronously.
813 rv = delegate->ReadData();
814 EXPECT_EQ(kUploadDataSize, rv);
815 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
816 EXPECT_EQ(1, delegate->on_data_read_count());
817 EXPECT_EQ(1, delegate->on_data_sent_count());
818 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
819 EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
820 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
821 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
822
823 // Destroy the delegate will destroy the stream, so we can get an end event
824 // for BIDIRECTIONAL_STREAM_ALIVE.
825 delegate.reset();
826 auto entries = net_log_observer_.GetEntries();
827
828 size_t index = ExpectLogContainsSomewhere(
829 entries, 0, NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
830 NetLogEventPhase::BEGIN);
831 // HTTP_STREAM_REQUEST is nested inside in BIDIRECTIONAL_STREAM_ALIVE.
832 index = ExpectLogContainsSomewhere(entries, index,
833 NetLogEventType::HTTP_STREAM_REQUEST,
834 NetLogEventPhase::BEGIN);
835 index = ExpectLogContainsSomewhere(entries, index,
836 NetLogEventType::HTTP_STREAM_REQUEST,
837 NetLogEventPhase::END);
838 // Headers received should happen after HTTP_STREAM_REQUEST.
839 index = ExpectLogContainsSomewhere(
840 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_RECV_HEADERS,
841 NetLogEventPhase::NONE);
842 // Trailers received should happen after headers received. It might happen
843 // before the reads complete.
844 ExpectLogContainsSomewhere(
845 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_RECV_TRAILERS,
846 NetLogEventPhase::NONE);
847 index = ExpectLogContainsSomewhere(
848 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA,
849 NetLogEventPhase::NONE);
850 index = ExpectLogContainsSomewhere(
851 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_READ_DATA,
852 NetLogEventPhase::NONE);
853 EXPECT_EQ(ERR_IO_PENDING, GetIntegerValueFromParams(entries[index], "rv"));
854
855 // Sent bytes. Sending data is always asynchronous.
856 index = ExpectLogContainsSomewhere(
857 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
858 NetLogEventPhase::NONE);
859 EXPECT_EQ(NetLogSourceType::BIDIRECTIONAL_STREAM, entries[index].source.type);
860 // Received bytes for asynchronous read.
861 index = ExpectLogContainsSomewhere(
862 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_RECEIVED,
863 NetLogEventPhase::NONE);
864 EXPECT_EQ(NetLogSourceType::BIDIRECTIONAL_STREAM, entries[index].source.type);
865 // Received bytes for synchronous read.
866 index = ExpectLogContainsSomewhere(
867 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_RECEIVED,
868 NetLogEventPhase::NONE);
869 EXPECT_EQ(NetLogSourceType::BIDIRECTIONAL_STREAM, entries[index].source.type);
870 ExpectLogContainsSomewhere(entries, index,
871 NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
872 NetLogEventPhase::END);
873 }
874
TEST_F(BidirectionalStreamTest,TestInterleaveReadDataAndSendData)875 TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) {
876 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
877 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
878 spdy::SpdySerializedFrame data_frame1(
879 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/false));
880 spdy::SpdySerializedFrame data_frame2(
881 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/false));
882 spdy::SpdySerializedFrame data_frame3(
883 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
884 MockWrite writes[] = {
885 CreateMockWrite(req, 0), CreateMockWrite(data_frame1, 3),
886 CreateMockWrite(data_frame2, 6), CreateMockWrite(data_frame3, 9),
887 };
888
889 spdy::SpdySerializedFrame resp(
890 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
891 spdy::SpdySerializedFrame response_body_frame1(
892 spdy_util_.ConstructSpdyDataFrame(1, false));
893 spdy::SpdySerializedFrame response_body_frame2(
894 spdy_util_.ConstructSpdyDataFrame(1, true));
895
896 MockRead reads[] = {
897 CreateMockRead(resp, 1),
898 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
899 CreateMockRead(response_body_frame1, 4),
900 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
901 CreateMockRead(response_body_frame2, 7),
902 MockRead(ASYNC, ERR_IO_PENDING, 8), // Force a pause.
903 MockRead(ASYNC, 0, 10),
904 };
905
906 InitSession(reads, writes, SocketTag());
907
908 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
909 request_info->method = "POST";
910 request_info->url = default_url_;
911 request_info->priority = LOWEST;
912 request_info->extra_headers.SetHeader(
913 net::HttpRequestHeaders::kContentLength,
914 base::NumberToString(kBodyDataSize * 3));
915
916 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
917 auto timer = std::make_unique<MockTimer>();
918 MockTimer* timer_ptr = timer.get();
919 auto delegate = std::make_unique<TestDelegateBase>(
920 read_buffer.get(), kReadBufferSize, std::move(timer));
921 delegate->set_do_not_start_read(true);
922 delegate->Start(std::move(request_info), http_session_.get());
923 // Send the request and receive response headers.
924 sequenced_data_->RunUntilPaused();
925 EXPECT_FALSE(timer_ptr->IsRunning());
926
927 // Send a DATA frame.
928 scoped_refptr<StringIOBuffer> buf =
929 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
930
931 // Send a DATA frame.
932 delegate->SendData(buf, buf->size(), false);
933 // ReadData and it should return asynchronously because no data is buffered.
934 int rv = delegate->ReadData();
935 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
936 // Deliver a DATA frame, and fire the timer.
937 sequenced_data_->Resume();
938 sequenced_data_->RunUntilPaused();
939 timer_ptr->Fire();
940 base::RunLoop().RunUntilIdle();
941 EXPECT_EQ(1, delegate->on_data_sent_count());
942 EXPECT_EQ(1, delegate->on_data_read_count());
943
944 // Send a DATA frame.
945 delegate->SendData(buf, buf->size(), false);
946 // ReadData and it should return asynchronously because no data is buffered.
947 rv = delegate->ReadData();
948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
949 // Deliver a DATA frame, and fire the timer.
950 sequenced_data_->Resume();
951 sequenced_data_->RunUntilPaused();
952 timer_ptr->Fire();
953 base::RunLoop().RunUntilIdle();
954 // Last DATA frame is read. Server half closes.
955 EXPECT_EQ(2, delegate->on_data_read_count());
956 EXPECT_EQ(2, delegate->on_data_sent_count());
957
958 // Send the last body frame. Client half closes.
959 delegate->SendData(buf, buf->size(), true);
960 sequenced_data_->Resume();
961 base::RunLoop().RunUntilIdle();
962 EXPECT_EQ(3, delegate->on_data_sent_count());
963
964 // OnClose is invoked since both sides are closed.
965 rv = delegate->ReadData();
966 EXPECT_THAT(rv, IsOk());
967
968 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
969 EXPECT_EQ(2, delegate->on_data_read_count());
970 EXPECT_EQ(3, delegate->on_data_sent_count());
971 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
972 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
973 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
974 }
975
TEST_F(BidirectionalStreamTest,TestCoalesceSmallDataBuffers)976 TEST_F(BidirectionalStreamTest, TestCoalesceSmallDataBuffers) {
977 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
978 kDefaultUrl, 1, kBodyDataSize * 1, LOWEST, nullptr, 0));
979 std::string body_data = "some really long piece of data";
980 spdy::SpdySerializedFrame data_frame1(
981 spdy_util_.ConstructSpdyDataFrame(1, body_data, /*fin=*/true));
982 MockWrite writes[] = {
983 CreateMockWrite(req, 0), CreateMockWrite(data_frame1, 1),
984 };
985
986 spdy::SpdySerializedFrame resp(
987 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
988 spdy::SpdySerializedFrame response_body_frame1(
989 spdy_util_.ConstructSpdyDataFrame(1, true));
990 MockRead reads[] = {
991 CreateMockRead(resp, 2),
992 MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause.
993 CreateMockRead(response_body_frame1, 4), MockRead(ASYNC, 0, 5),
994 };
995
996 InitSession(reads, writes, SocketTag());
997
998 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
999 request_info->method = "POST";
1000 request_info->url = default_url_;
1001 request_info->priority = LOWEST;
1002 request_info->extra_headers.SetHeader(
1003 net::HttpRequestHeaders::kContentLength,
1004 base::NumberToString(kBodyDataSize * 1));
1005
1006 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1007 auto timer = std::make_unique<MockTimer>();
1008 auto delegate = std::make_unique<TestDelegateBase>(
1009 read_buffer.get(), kReadBufferSize, std::move(timer));
1010 delegate->set_do_not_start_read(true);
1011 TestCompletionCallback callback;
1012 delegate->Start(std::move(request_info), http_session_.get(),
1013 callback.callback());
1014 // Wait until the stream is ready.
1015 callback.WaitForResult();
1016 // Send a DATA frame.
1017 scoped_refptr<StringIOBuffer> buf =
1018 base::MakeRefCounted<StringIOBuffer>(body_data.substr(0, 5));
1019 scoped_refptr<StringIOBuffer> buf2 = base::MakeRefCounted<StringIOBuffer>(
1020 body_data.substr(5, body_data.size() - 5));
1021 delegate->SendvData({buf, buf2.get()}, {buf->size(), buf2->size()}, true);
1022 sequenced_data_->RunUntilPaused(); // OnHeadersReceived.
1023 // ReadData and it should return asynchronously because no data is buffered.
1024 EXPECT_THAT(delegate->ReadData(), IsError(ERR_IO_PENDING));
1025 sequenced_data_->Resume();
1026 base::RunLoop().RunUntilIdle();
1027 EXPECT_EQ(1, delegate->on_data_sent_count());
1028 EXPECT_EQ(1, delegate->on_data_read_count());
1029
1030 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1031 EXPECT_EQ(1, delegate->on_data_read_count());
1032 EXPECT_EQ(1, delegate->on_data_sent_count());
1033 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1034 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1035 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1036
1037 auto entries = net_log_observer_.GetEntries();
1038 size_t index = ExpectLogContainsSomewhere(
1039 entries, 0, NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA,
1040 NetLogEventPhase::NONE);
1041 EXPECT_EQ(2, GetIntegerValueFromParams(entries[index], "num_buffers"));
1042
1043 index = ExpectLogContainsSomewhereAfter(
1044 entries, index,
1045 NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED,
1046 NetLogEventPhase::BEGIN);
1047 EXPECT_EQ(2,
1048 GetIntegerValueFromParams(entries[index], "num_buffers_coalesced"));
1049
1050 index = ExpectLogContainsSomewhereAfter(
1051 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
1052 NetLogEventPhase::NONE);
1053 EXPECT_EQ(buf->size(),
1054 GetIntegerValueFromParams(entries[index], "byte_count"));
1055
1056 index = ExpectLogContainsSomewhereAfter(
1057 entries, index + 1, NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
1058 NetLogEventPhase::NONE);
1059 EXPECT_EQ(buf2->size(),
1060 GetIntegerValueFromParams(entries[index], "byte_count"));
1061
1062 ExpectLogContainsSomewhere(
1063 entries, index,
1064 NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED,
1065 NetLogEventPhase::END);
1066 }
1067
1068 // Tests that BidirectionalStreamSpdyImpl::OnClose will complete any remaining
1069 // read even if the read queue is empty.
TEST_F(BidirectionalStreamTest,TestCompleteAsyncRead)1070 TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) {
1071 spdy::SpdySerializedFrame req(
1072 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1073 MockWrite writes[] = {CreateMockWrite(req, 0)};
1074
1075 spdy::SpdySerializedFrame resp(
1076 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1077
1078 spdy::SpdySerializedFrame response_body_frame(
1079 spdy_util_.ConstructSpdyDataFrame(1, "", true));
1080
1081 MockRead reads[] = {
1082 CreateMockRead(resp, 1),
1083 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
1084 CreateMockRead(response_body_frame, 3), MockRead(SYNCHRONOUS, 0, 4),
1085 };
1086
1087 InitSession(reads, writes, SocketTag());
1088
1089 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1090 request_info->method = "GET";
1091 request_info->url = default_url_;
1092 request_info->priority = LOWEST;
1093 request_info->end_stream_on_headers = true;
1094
1095 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1096 auto timer = std::make_unique<MockTimer>();
1097 MockTimer* timer_ptr = timer.get();
1098 auto delegate = std::make_unique<TestDelegateBase>(
1099 read_buffer.get(), kReadBufferSize, std::move(timer));
1100 delegate->set_do_not_start_read(true);
1101 delegate->Start(std::move(request_info), http_session_.get());
1102 // Write request, and deliver response headers.
1103 sequenced_data_->RunUntilPaused();
1104 EXPECT_FALSE(timer_ptr->IsRunning());
1105
1106 // ReadData should return asynchronously because no data is buffered.
1107 int rv = delegate->ReadData();
1108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1109 // Deliver END_STREAM.
1110 // OnClose should trigger completion of the remaining read.
1111 sequenced_data_->Resume();
1112 base::RunLoop().RunUntilIdle();
1113
1114 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1115 EXPECT_EQ(1, delegate->on_data_read_count());
1116 EXPECT_EQ(0u, delegate->data_received().size());
1117 EXPECT_EQ(0, delegate->on_data_sent_count());
1118 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1119 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1120 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1121 }
1122
TEST_F(BidirectionalStreamTest,TestBuffering)1123 TEST_F(BidirectionalStreamTest, TestBuffering) {
1124 spdy::SpdySerializedFrame req(
1125 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1126 MockWrite writes[] = {CreateMockWrite(req, 0)};
1127
1128 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
1129 spdy::SpdySerializedFrame resp(
1130 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
1131
1132 spdy::SpdySerializedFrame body_frame(
1133 spdy_util_.ConstructSpdyDataFrame(1, false));
1134 // Last body frame has END_STREAM flag set.
1135 spdy::SpdySerializedFrame last_body_frame(
1136 spdy_util_.ConstructSpdyDataFrame(1, true));
1137
1138 MockRead reads[] = {
1139 CreateMockRead(resp, 1),
1140 CreateMockRead(body_frame, 2),
1141 CreateMockRead(body_frame, 3),
1142 MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
1143 CreateMockRead(last_body_frame, 5),
1144 MockRead(SYNCHRONOUS, 0, 6),
1145 };
1146
1147 InitSession(reads, writes, SocketTag());
1148
1149 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1150 request_info->method = "GET";
1151 request_info->url = default_url_;
1152 request_info->priority = LOWEST;
1153 request_info->end_stream_on_headers = true;
1154
1155 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1156 auto timer = std::make_unique<MockTimer>();
1157 MockTimer* timer_ptr = timer.get();
1158 auto delegate = std::make_unique<TestDelegateBase>(
1159 read_buffer.get(), kReadBufferSize, std::move(timer));
1160 delegate->Start(std::move(request_info), http_session_.get());
1161 // Deliver two DATA frames together.
1162 sequenced_data_->RunUntilPaused();
1163 EXPECT_TRUE(timer_ptr->IsRunning());
1164 timer_ptr->Fire();
1165 base::RunLoop().RunUntilIdle();
1166 // This should trigger |more_read_data_pending_| to execute the task at a
1167 // later time, and Delegate::OnReadComplete should not have been called.
1168 EXPECT_TRUE(timer_ptr->IsRunning());
1169 EXPECT_EQ(0, delegate->on_data_read_count());
1170
1171 // Fire the timer now, the two DATA frame should be combined into one
1172 // single Delegate::OnReadComplete callback.
1173 timer_ptr->Fire();
1174 base::RunLoop().RunUntilIdle();
1175 EXPECT_EQ(1, delegate->on_data_read_count());
1176 EXPECT_EQ(kUploadDataSize * 2,
1177 static_cast<int>(delegate->data_received().size()));
1178
1179 // Deliver last DATA frame and EOF. There will be an additional
1180 // Delegate::OnReadComplete callback.
1181 sequenced_data_->Resume();
1182 base::RunLoop().RunUntilIdle();
1183
1184 EXPECT_EQ(2, delegate->on_data_read_count());
1185 EXPECT_EQ(kUploadDataSize * 3,
1186 static_cast<int>(delegate->data_received().size()));
1187
1188 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
1189 EXPECT_EQ("200", response_headers.find(":status")->second);
1190 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1191 EXPECT_EQ(0, delegate->on_data_sent_count());
1192 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1193 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1194 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1195 }
1196
TEST_F(BidirectionalStreamTest,TestBufferingWithTrailers)1197 TEST_F(BidirectionalStreamTest, TestBufferingWithTrailers) {
1198 spdy::SpdySerializedFrame req(
1199 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1200 MockWrite writes[] = {
1201 CreateMockWrite(req, 0),
1202 };
1203
1204 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
1205 spdy::SpdySerializedFrame resp(
1206 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
1207
1208 spdy::SpdySerializedFrame body_frame(
1209 spdy_util_.ConstructSpdyDataFrame(1, false));
1210
1211 spdy::Http2HeaderBlock trailers;
1212 trailers["foo"] = "bar";
1213 spdy::SpdySerializedFrame response_trailers(
1214 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers), true));
1215
1216 MockRead reads[] = {
1217 CreateMockRead(resp, 1),
1218 CreateMockRead(body_frame, 2),
1219 CreateMockRead(body_frame, 3),
1220 CreateMockRead(body_frame, 4),
1221 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause.
1222 CreateMockRead(response_trailers, 6),
1223 MockRead(SYNCHRONOUS, 0, 7),
1224 };
1225
1226 InitSession(reads, writes, SocketTag());
1227
1228 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1229 auto timer = std::make_unique<MockTimer>();
1230 MockTimer* timer_ptr = timer.get();
1231 auto delegate = std::make_unique<TestDelegateBase>(
1232 read_buffer.get(), kReadBufferSize, std::move(timer));
1233
1234 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1235 request_info->method = "GET";
1236 request_info->url = default_url_;
1237 request_info->priority = LOWEST;
1238 request_info->end_stream_on_headers = true;
1239
1240 delegate->Start(std::move(request_info), http_session_.get());
1241 // Deliver all three DATA frames together.
1242 sequenced_data_->RunUntilPaused();
1243 EXPECT_TRUE(timer_ptr->IsRunning());
1244 timer_ptr->Fire();
1245 base::RunLoop().RunUntilIdle();
1246 // This should trigger |more_read_data_pending_| to execute the task at a
1247 // later time, and Delegate::OnReadComplete should not have been called.
1248 EXPECT_TRUE(timer_ptr->IsRunning());
1249 EXPECT_EQ(0, delegate->on_data_read_count());
1250
1251 // Deliver trailers. Remaining read should be completed, since OnClose is
1252 // called right after OnTrailersReceived. The three DATA frames should be
1253 // delivered in a single OnReadCompleted callback.
1254 sequenced_data_->Resume();
1255 base::RunLoop().RunUntilIdle();
1256
1257 EXPECT_EQ(1, delegate->on_data_read_count());
1258 EXPECT_EQ(kUploadDataSize * 3,
1259 static_cast<int>(delegate->data_received().size()));
1260 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
1261 EXPECT_EQ("200", response_headers.find(":status")->second);
1262 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1263 EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
1264 EXPECT_EQ(0, delegate->on_data_sent_count());
1265 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1266 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1267 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1268 }
1269
TEST_F(BidirectionalStreamTest,DeleteStreamAfterSendData)1270 TEST_F(BidirectionalStreamTest, DeleteStreamAfterSendData) {
1271 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1272 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
1273 spdy::SpdySerializedFrame data_frame(
1274 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/false));
1275 spdy::SpdySerializedFrame rst(
1276 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
1277
1278 MockWrite writes[] = {
1279 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
1280 CreateMockWrite(rst, 5),
1281 };
1282
1283 spdy::SpdySerializedFrame resp(
1284 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1285 MockRead reads[] = {
1286 CreateMockRead(resp, 1),
1287 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
1288 MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause.
1289 MockRead(ASYNC, 0, 6),
1290 };
1291
1292 InitSession(reads, writes, SocketTag());
1293
1294 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1295 request_info->method = "POST";
1296 request_info->url = default_url_;
1297 request_info->priority = LOWEST;
1298 request_info->extra_headers.SetHeader(
1299 net::HttpRequestHeaders::kContentLength,
1300 base::NumberToString(kBodyDataSize * 3));
1301
1302 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1303 auto delegate =
1304 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
1305 delegate->set_do_not_start_read(true);
1306 delegate->Start(std::move(request_info), http_session_.get());
1307 // Send the request and receive response headers.
1308 sequenced_data_->RunUntilPaused();
1309 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1310
1311 // Send a DATA frame.
1312 scoped_refptr<StringIOBuffer> buf =
1313 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
1314 delegate->SendData(buf, buf->size(), false);
1315 sequenced_data_->Resume();
1316 base::RunLoop().RunUntilIdle();
1317
1318 delegate->DeleteStream();
1319 sequenced_data_->Resume();
1320 base::RunLoop().RunUntilIdle();
1321
1322 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1323 EXPECT_EQ(0, delegate->on_data_read_count());
1324 // OnDataSent may or may not have been invoked.
1325 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1326 // Bytes sent excludes the RST frame.
1327 EXPECT_EQ(
1328 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
1329 delegate->GetTotalSentBytes());
1330 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1331 }
1332
TEST_F(BidirectionalStreamTest,DeleteStreamDuringReadData)1333 TEST_F(BidirectionalStreamTest, DeleteStreamDuringReadData) {
1334 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1335 kDefaultUrl, 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
1336 spdy::SpdySerializedFrame rst(
1337 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
1338
1339 MockWrite writes[] = {
1340 CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
1341 };
1342
1343 spdy::SpdySerializedFrame resp(
1344 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1345 spdy::SpdySerializedFrame response_body_frame(
1346 spdy_util_.ConstructSpdyDataFrame(1, false));
1347
1348 MockRead reads[] = {
1349 CreateMockRead(resp, 1),
1350 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
1351 CreateMockRead(response_body_frame, 3), MockRead(ASYNC, 0, 5),
1352 };
1353
1354 InitSession(reads, writes, SocketTag());
1355
1356 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1357 request_info->method = "POST";
1358 request_info->url = default_url_;
1359 request_info->priority = LOWEST;
1360 request_info->extra_headers.SetHeader(
1361 net::HttpRequestHeaders::kContentLength,
1362 base::NumberToString(kBodyDataSize * 3));
1363
1364 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1365 auto delegate =
1366 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
1367 delegate->set_do_not_start_read(true);
1368 delegate->Start(std::move(request_info), http_session_.get());
1369 // Send the request and receive response headers.
1370 base::RunLoop().RunUntilIdle();
1371
1372 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1373 // Delete the stream after ReadData returns ERR_IO_PENDING.
1374 int rv = delegate->ReadData();
1375 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1377 delegate->DeleteStream();
1378 sequenced_data_->Resume();
1379 base::RunLoop().RunUntilIdle();
1380
1381 EXPECT_EQ(0, delegate->on_data_read_count());
1382 EXPECT_EQ(0, delegate->on_data_sent_count());
1383 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1384 // Bytes sent excludes the RST frame.
1385 EXPECT_EQ(
1386 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
1387 delegate->GetTotalSentBytes());
1388 // Response body frame isn't read becase stream is deleted once read returns
1389 // ERR_IO_PENDING.
1390 EXPECT_EQ(CountReadBytes(base::make_span(reads).first(std::size(reads) - 2)),
1391 delegate->GetTotalReceivedBytes());
1392 }
1393
1394 // Receiving a header with uppercase ASCII will result in a protocol error,
1395 // which should be propagated via Delegate::OnFailed.
TEST_F(BidirectionalStreamTest,PropagateProtocolError)1396 TEST_F(BidirectionalStreamTest, PropagateProtocolError) {
1397 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1398 kDefaultUrl, 1, kBodyDataSize * 3, LOW, nullptr, 0));
1399 spdy::SpdySerializedFrame rst(
1400 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
1401
1402 MockWrite writes[] = {
1403 CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
1404 };
1405
1406 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
1407 spdy::SpdySerializedFrame resp(
1408 spdy_util_.ConstructSpdyGetReply(kExtraHeaders, 1, 1));
1409
1410 MockRead reads[] = {
1411 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3),
1412 };
1413
1414 InitSession(reads, writes, SocketTag());
1415
1416 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1417 request_info->method = "POST";
1418 request_info->url = default_url_;
1419 request_info->extra_headers.SetHeader(
1420 net::HttpRequestHeaders::kContentLength,
1421 base::NumberToString(kBodyDataSize * 3));
1422
1423 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1424 auto delegate =
1425 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
1426 delegate->SetRunUntilCompletion(true);
1427 delegate->Start(std::move(request_info), http_session_.get());
1428
1429 base::RunLoop().RunUntilIdle();
1430 EXPECT_THAT(delegate->error(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1431 EXPECT_EQ(delegate->response_headers().end(),
1432 delegate->response_headers().find(":status"));
1433 EXPECT_EQ(0, delegate->on_data_read_count());
1434 EXPECT_EQ(0, delegate->on_data_sent_count());
1435 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1436 // BidirectionalStreamSpdyStreamJob does not count the bytes sent for |rst|
1437 // because it is sent after SpdyStream::Delegate::OnClose is called.
1438 EXPECT_EQ(CountWriteBytes(base::make_span(writes, 1u)),
1439 delegate->GetTotalSentBytes());
1440 EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
1441
1442 auto entries = net_log_observer_.GetEntries();
1443
1444 size_t index = ExpectLogContainsSomewhere(
1445 entries, 0, NetLogEventType::BIDIRECTIONAL_STREAM_READY,
1446 NetLogEventPhase::NONE);
1447 EXPECT_TRUE(
1448 GetBooleanValueFromParams(entries[index], "request_headers_sent"));
1449
1450 index = ExpectLogContainsSomewhere(
1451 entries, index, NetLogEventType::BIDIRECTIONAL_STREAM_FAILED,
1452 NetLogEventPhase::NONE);
1453 EXPECT_EQ(ERR_HTTP2_PROTOCOL_ERROR,
1454 GetNetErrorCodeFromParams(entries[index]));
1455 }
1456
TEST_F(BidirectionalStreamTest,DeleteStreamDuringOnHeadersReceived)1457 TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnHeadersReceived) {
1458 spdy::SpdySerializedFrame req(
1459 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1460
1461 spdy::SpdySerializedFrame rst(
1462 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
1463 MockWrite writes[] = {
1464 CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
1465 };
1466
1467 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
1468 spdy::SpdySerializedFrame resp(
1469 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
1470
1471 MockRead reads[] = {
1472 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3),
1473 };
1474
1475 InitSession(reads, writes, SocketTag());
1476
1477 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1478 request_info->method = "GET";
1479 request_info->url = default_url_;
1480 request_info->priority = LOWEST;
1481 request_info->end_stream_on_headers = true;
1482
1483 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1484 auto delegate = std::make_unique<DeleteStreamDelegate>(
1485 read_buffer.get(), kReadBufferSize,
1486 DeleteStreamDelegate::Phase::ON_HEADERS_RECEIVED);
1487 delegate->SetRunUntilCompletion(true);
1488 delegate->Start(std::move(request_info), http_session_.get());
1489 // Makes sure delegate does not get called.
1490 base::RunLoop().RunUntilIdle();
1491 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
1492 EXPECT_EQ("200", response_headers.find(":status")->second);
1493 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1494 EXPECT_EQ(0u, delegate->data_received().size());
1495 EXPECT_EQ(0, delegate->on_data_sent_count());
1496 EXPECT_EQ(0, delegate->on_data_read_count());
1497
1498 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1499 // Bytes sent excludes the RST frame.
1500 EXPECT_EQ(
1501 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
1502 delegate->GetTotalSentBytes());
1503 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1504 }
1505
TEST_F(BidirectionalStreamTest,DeleteStreamDuringOnDataRead)1506 TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnDataRead) {
1507 spdy::SpdySerializedFrame req(
1508 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1509
1510 spdy::SpdySerializedFrame rst(
1511 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
1512 MockWrite writes[] = {
1513 CreateMockWrite(req, 0), CreateMockWrite(rst, 3),
1514 };
1515
1516 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
1517 spdy::SpdySerializedFrame resp(
1518 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
1519
1520 spdy::SpdySerializedFrame response_body_frame(
1521 spdy_util_.ConstructSpdyDataFrame(1, false));
1522
1523 MockRead reads[] = {
1524 CreateMockRead(resp, 1), CreateMockRead(response_body_frame, 2),
1525 MockRead(ASYNC, 0, 4),
1526 };
1527
1528 InitSession(reads, writes, SocketTag());
1529
1530 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1531 request_info->method = "GET";
1532 request_info->url = default_url_;
1533 request_info->priority = LOWEST;
1534 request_info->end_stream_on_headers = true;
1535
1536 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1537 auto delegate = std::make_unique<DeleteStreamDelegate>(
1538 read_buffer.get(), kReadBufferSize,
1539 DeleteStreamDelegate::Phase::ON_DATA_READ);
1540 delegate->SetRunUntilCompletion(true);
1541 delegate->Start(std::move(request_info), http_session_.get());
1542 // Makes sure delegate does not get called.
1543 base::RunLoop().RunUntilIdle();
1544 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
1545 EXPECT_EQ("200", response_headers.find(":status")->second);
1546 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1547 EXPECT_EQ(kUploadDataSize * 1,
1548 static_cast<int>(delegate->data_received().size()));
1549 EXPECT_EQ(0, delegate->on_data_sent_count());
1550
1551 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1552 // Bytes sent excludes the RST frame.
1553 EXPECT_EQ(
1554 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
1555 delegate->GetTotalSentBytes());
1556 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1557 }
1558
TEST_F(BidirectionalStreamTest,DeleteStreamDuringOnTrailersReceived)1559 TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnTrailersReceived) {
1560 spdy::SpdySerializedFrame req(
1561 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1562
1563 spdy::SpdySerializedFrame rst(
1564 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
1565 MockWrite writes[] = {
1566 CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
1567 };
1568
1569 const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
1570 spdy::SpdySerializedFrame resp(
1571 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
1572
1573 spdy::SpdySerializedFrame response_body_frame(
1574 spdy_util_.ConstructSpdyDataFrame(1, false));
1575
1576 spdy::Http2HeaderBlock trailers;
1577 trailers["foo"] = "bar";
1578 spdy::SpdySerializedFrame response_trailers(
1579 spdy_util_.ConstructSpdyResponseHeaders(1, std::move(trailers), true));
1580
1581 MockRead reads[] = {
1582 CreateMockRead(resp, 1), CreateMockRead(response_body_frame, 2),
1583 CreateMockRead(response_trailers, 3), MockRead(ASYNC, 0, 5),
1584 };
1585
1586 InitSession(reads, writes, SocketTag());
1587
1588 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1589 request_info->method = "GET";
1590 request_info->url = default_url_;
1591 request_info->priority = LOWEST;
1592 request_info->end_stream_on_headers = true;
1593
1594 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1595 auto delegate = std::make_unique<DeleteStreamDelegate>(
1596 read_buffer.get(), kReadBufferSize,
1597 DeleteStreamDelegate::Phase::ON_TRAILERS_RECEIVED);
1598 delegate->SetRunUntilCompletion(true);
1599 delegate->Start(std::move(request_info), http_session_.get());
1600 // Makes sure delegate does not get called.
1601 base::RunLoop().RunUntilIdle();
1602 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
1603 EXPECT_EQ("200", response_headers.find(":status")->second);
1604 EXPECT_EQ("header-value", response_headers.find("header-name")->second);
1605 EXPECT_EQ("bar", delegate->trailers().find("foo")->second);
1606 EXPECT_EQ(0, delegate->on_data_sent_count());
1607 // OnDataRead may or may not have been fired before the stream is
1608 // deleted.
1609 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1610 // Bytes sent excludes the RST frame.
1611 EXPECT_EQ(
1612 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
1613 delegate->GetTotalSentBytes());
1614 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1615 }
1616
TEST_F(BidirectionalStreamTest,DeleteStreamDuringOnFailed)1617 TEST_F(BidirectionalStreamTest, DeleteStreamDuringOnFailed) {
1618 spdy::SpdySerializedFrame req(
1619 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1620
1621 spdy::SpdySerializedFrame rst(
1622 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_PROTOCOL_ERROR));
1623
1624 MockWrite writes[] = {
1625 CreateMockWrite(req, 0), CreateMockWrite(rst, 2),
1626 };
1627
1628 const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
1629 spdy::SpdySerializedFrame resp(
1630 spdy_util_.ConstructSpdyGetReply(kExtraHeaders, 1, 1));
1631
1632 MockRead reads[] = {
1633 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3),
1634 };
1635
1636 InitSession(reads, writes, SocketTag());
1637
1638 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1639 request_info->method = "GET";
1640 request_info->url = default_url_;
1641 request_info->priority = LOWEST;
1642 request_info->end_stream_on_headers = true;
1643
1644 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1645 auto delegate = std::make_unique<DeleteStreamDelegate>(
1646 read_buffer.get(), kReadBufferSize,
1647 DeleteStreamDelegate::Phase::ON_FAILED);
1648 delegate->SetRunUntilCompletion(true);
1649 delegate->Start(std::move(request_info), http_session_.get());
1650 // Makes sure delegate does not get called.
1651 base::RunLoop().RunUntilIdle();
1652 EXPECT_EQ(delegate->response_headers().end(),
1653 delegate->response_headers().find(":status"));
1654 EXPECT_EQ(0, delegate->on_data_sent_count());
1655 EXPECT_EQ(0, delegate->on_data_read_count());
1656 EXPECT_THAT(delegate->error(), IsError(ERR_HTTP2_PROTOCOL_ERROR));
1657
1658 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1659 // Bytes sent excludes the RST frame.
1660 EXPECT_EQ(
1661 CountWriteBytes(base::make_span(writes).first(std::size(writes) - 1)),
1662 delegate->GetTotalSentBytes());
1663 EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
1664 }
1665
TEST_F(BidirectionalStreamTest,TestHonorAlternativeServiceHeader)1666 TEST_F(BidirectionalStreamTest, TestHonorAlternativeServiceHeader) {
1667 spdy::SpdySerializedFrame req(
1668 spdy_util_.ConstructSpdyGet(kDefaultUrl, 1, LOWEST));
1669 MockWrite writes[] = {CreateMockWrite(req, 0)};
1670
1671 std::string alt_svc_header_value =
1672 quic::AlpnForVersion(DefaultSupportedQuicVersions().front());
1673 alt_svc_header_value.append("=\"www.example.org:443\"");
1674 const char* const kExtraResponseHeaders[] = {"alt-svc",
1675 alt_svc_header_value.c_str()};
1676 spdy::SpdySerializedFrame resp(
1677 spdy_util_.ConstructSpdyGetReply(kExtraResponseHeaders, 1, 1));
1678 spdy::SpdySerializedFrame body_frame(
1679 spdy_util_.ConstructSpdyDataFrame(1, true));
1680
1681 MockRead reads[] = {
1682 CreateMockRead(resp, 1), CreateMockRead(body_frame, 2),
1683 MockRead(SYNCHRONOUS, 0, 3),
1684 };
1685
1686 // Enable QUIC so that the alternative service header can be added to
1687 // HttpServerProperties.
1688 session_deps_.enable_quic = true;
1689 InitSession(reads, writes, SocketTag());
1690
1691 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1692 request_info->method = "GET";
1693 request_info->url = default_url_;
1694 request_info->priority = LOWEST;
1695 request_info->end_stream_on_headers = true;
1696
1697 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1698 auto timer = std::make_unique<MockTimer>();
1699 auto delegate = std::make_unique<TestDelegateBase>(
1700 read_buffer.get(), kReadBufferSize, std::move(timer));
1701 delegate->SetRunUntilCompletion(true);
1702 delegate->Start(std::move(request_info), http_session_.get());
1703
1704 const spdy::Http2HeaderBlock& response_headers = delegate->response_headers();
1705 EXPECT_EQ("200", response_headers.find(":status")->second);
1706 EXPECT_EQ(alt_svc_header_value, response_headers.find("alt-svc")->second);
1707 EXPECT_EQ(0, delegate->on_data_sent_count());
1708 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol());
1709 EXPECT_EQ(kUploadData, delegate->data_received());
1710 EXPECT_EQ(CountWriteBytes(writes), delegate->GetTotalSentBytes());
1711 EXPECT_EQ(CountReadBytes(reads), delegate->GetTotalReceivedBytes());
1712
1713 AlternativeServiceInfoVector alternative_service_info_vector =
1714 http_session_->http_server_properties()->GetAlternativeServiceInfos(
1715 url::SchemeHostPort(default_url_), NetworkAnonymizationKey());
1716 ASSERT_EQ(1u, alternative_service_info_vector.size());
1717 AlternativeService alternative_service(kProtoQUIC, "www.example.org", 443);
1718 EXPECT_EQ(alternative_service,
1719 alternative_service_info_vector[0].alternative_service());
1720 }
1721
1722 // Test that a BidirectionalStream created with a specific tag, tags the
1723 // underlying socket appropriately.
TEST_F(BidirectionalStreamTest,Tagging)1724 TEST_F(BidirectionalStreamTest, Tagging) {
1725 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
1726 kDefaultUrl, 1, kBodyDataSize, LOW, nullptr, 0));
1727 spdy::SpdySerializedFrame data_frame(
1728 spdy_util_.ConstructSpdyDataFrame(1, kBodyDataString, /*fin=*/true));
1729 MockWrite writes[] = {
1730 CreateMockWrite(req, 0), CreateMockWrite(data_frame, 3),
1731 };
1732 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0));
1733 spdy::SpdySerializedFrame response_body_frame(
1734 spdy_util_.ConstructSpdyDataFrame(1, /*fin=*/true));
1735 MockRead reads[] = {
1736 CreateMockRead(resp, 1),
1737 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause.
1738 CreateMockRead(response_body_frame, 4), MockRead(ASYNC, 0, 5),
1739 };
1740 #if BUILDFLAG(IS_ANDROID)
1741 SocketTag tag(0x12345678, 0x87654321);
1742 #else
1743 SocketTag tag;
1744 #endif
1745 InitSession(reads, writes, tag);
1746
1747 auto request_info = std::make_unique<BidirectionalStreamRequestInfo>();
1748 request_info->method = "POST";
1749 request_info->url = default_url_;
1750 request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength,
1751 base::NumberToString(kBodyDataSize));
1752 request_info->socket_tag = tag;
1753 auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(kReadBufferSize);
1754 auto delegate =
1755 std::make_unique<TestDelegateBase>(read_buffer.get(), kReadBufferSize);
1756 delegate->Start(std::move(request_info), http_session_.get());
1757 sequenced_data_->RunUntilPaused();
1758
1759 EXPECT_EQ(socket_factory_->GetLastProducedTCPSocket()->tag(), tag);
1760 EXPECT_TRUE(
1761 socket_factory_->GetLastProducedTCPSocket()->tagged_before_connected());
1762 void* socket = socket_factory_->GetLastProducedTCPSocket();
1763
1764 scoped_refptr<StringIOBuffer> buf =
1765 base::MakeRefCounted<StringIOBuffer>(kBodyDataString);
1766 delegate->SendData(buf.get(), buf->size(), true);
1767 sequenced_data_->Resume();
1768 base::RunLoop().RunUntilIdle();
1769
1770 EXPECT_EQ(socket, socket_factory_->GetLastProducedTCPSocket());
1771 }
1772
1773 } // namespace net
1774