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