Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/bidirectional_stream.h" | 5 #include "net/http/bidirectional_stream.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_piece.h" | 11 #include "base/strings/string_piece.h" |
| 12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 13 #include "base/timer/mock_timer.h" | 13 #include "base/timer/mock_timer.h" |
| 14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/base/test_data_directory.h" | 15 #include "net/base/test_data_directory.h" |
| 16 #include "net/http/bidirectional_stream_request_info.h" | 16 #include "net/http/bidirectional_stream_request_info.h" |
| 17 #include "net/http/http_network_session.h" | 17 #include "net/http/http_network_session.h" |
| 18 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" |
| 19 #include "net/http/http_server_properties.h" | 19 #include "net/http/http_server_properties.h" |
| 20 #include "net/log/net_log.h" | 20 #include "net/log/net_log.h" |
| 21 #include "net/log/test_net_log.h" | |
| 22 #include "net/log/test_net_log_util.h" | |
| 21 #include "net/socket/socket_test_util.h" | 23 #include "net/socket/socket_test_util.h" |
| 22 #include "net/spdy/spdy_session.h" | 24 #include "net/spdy/spdy_session.h" |
| 23 #include "net/spdy/spdy_test_util_common.h" | 25 #include "net/spdy/spdy_test_util_common.h" |
| 24 #include "net/test/cert_test_util.h" | 26 #include "net/test/cert_test_util.h" |
| 25 #include "net/url_request/url_request_test_util.h" | 27 #include "net/url_request/url_request_test_util.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 29 |
| 28 namespace net { | 30 namespace net { |
| 29 | 31 |
| 30 namespace { | 32 namespace { |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 } // namespace | 297 } // namespace |
| 296 | 298 |
| 297 class BidirectionalStreamTest : public testing::TestWithParam<bool> { | 299 class BidirectionalStreamTest : public testing::TestWithParam<bool> { |
| 298 public: | 300 public: |
| 299 BidirectionalStreamTest() | 301 BidirectionalStreamTest() |
| 300 : spdy_util_(kProtoHTTP2, true), | 302 : spdy_util_(kProtoHTTP2, true), |
| 301 session_deps_(kProtoHTTP2), | 303 session_deps_(kProtoHTTP2), |
| 302 ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { | 304 ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { |
| 303 ssl_data_.SetNextProto(kProtoHTTP2); | 305 ssl_data_.SetNextProto(kProtoHTTP2); |
| 304 ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); | 306 ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); |
| 307 net_log_.SetCaptureMode(NetLogCaptureMode::IncludeSocketBytes()); | |
| 305 } | 308 } |
| 306 | 309 |
| 307 protected: | 310 protected: |
| 308 void TearDown() override { | 311 void TearDown() override { |
| 309 if (sequenced_data_) { | 312 if (sequenced_data_) { |
| 310 EXPECT_TRUE(sequenced_data_->AllReadDataConsumed()); | 313 EXPECT_TRUE(sequenced_data_->AllReadDataConsumed()); |
| 311 EXPECT_TRUE(sequenced_data_->AllWriteDataConsumed()); | 314 EXPECT_TRUE(sequenced_data_->AllWriteDataConsumed()); |
| 312 } | 315 } |
| 313 } | 316 } |
| 314 | 317 |
| 315 // Initializes the session using SequencedSocketData. | 318 // Initializes the session using SequencedSocketData. |
| 316 void InitSession(MockRead* reads, | 319 void InitSession(MockRead* reads, |
| 317 size_t reads_count, | 320 size_t reads_count, |
| 318 MockWrite* writes, | 321 MockWrite* writes, |
| 319 size_t writes_count, | 322 size_t writes_count, |
| 320 const SpdySessionKey& key) { | 323 const SpdySessionKey& key) { |
| 321 ASSERT_TRUE(ssl_data_.cert.get()); | 324 ASSERT_TRUE(ssl_data_.cert.get()); |
| 322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data_); | 325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data_); |
| 323 sequenced_data_.reset( | 326 sequenced_data_.reset( |
| 324 new SequencedSocketData(reads, reads_count, writes, writes_count)); | 327 new SequencedSocketData(reads, reads_count, writes, writes_count)); |
| 325 session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get()); | 328 session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get()); |
| 329 session_deps_.net_log = net_log_.bound().net_log(); | |
| 326 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); | 330 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
| 327 session_ = CreateSecureSpdySession(http_session_.get(), key, BoundNetLog()); | 331 session_ = |
| 332 CreateSecureSpdySession(http_session_.get(), key, net_log_.bound()); | |
| 328 } | 333 } |
| 329 | 334 |
| 335 BoundTestNetLog net_log_; | |
| 330 SpdyTestUtil spdy_util_; | 336 SpdyTestUtil spdy_util_; |
| 331 SpdySessionDependencies session_deps_; | 337 SpdySessionDependencies session_deps_; |
| 332 scoped_ptr<SequencedSocketData> sequenced_data_; | 338 scoped_ptr<SequencedSocketData> sequenced_data_; |
| 333 scoped_ptr<HttpNetworkSession> http_session_; | 339 scoped_ptr<HttpNetworkSession> http_session_; |
| 334 | 340 |
| 335 private: | 341 private: |
| 336 SSLSocketDataProvider ssl_data_; | 342 SSLSocketDataProvider ssl_data_; |
| 337 base::WeakPtr<SpdySession> session_; | 343 base::WeakPtr<SpdySession> session_; |
| 338 }; | 344 }; |
| 339 | 345 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 EXPECT_EQ("header-value", response_headers.find("header-name")->second); | 443 EXPECT_EQ("header-value", response_headers.find("header-name")->second); |
| 438 EXPECT_EQ(1, delegate->on_data_read_count()); | 444 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 439 EXPECT_EQ(0, delegate->on_data_sent_count()); | 445 EXPECT_EQ(0, delegate->on_data_sent_count()); |
| 440 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); | 446 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); |
| 441 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), | 447 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), |
| 442 delegate->GetTotalSentBytes()); | 448 delegate->GetTotalSentBytes()); |
| 443 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), | 449 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), |
| 444 delegate->GetTotalReceivedBytes()); | 450 delegate->GetTotalReceivedBytes()); |
| 445 } | 451 } |
| 446 | 452 |
| 453 TEST_F(BidirectionalStreamTest, TestContainFullBytes) { | |
| 454 BufferedSpdyFramer framer(spdy_util_.spdy_version()); | |
| 455 | |
| 456 scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( | |
| 457 "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0)); | |
| 458 scoped_ptr<SpdySerializedFrame> data_frame( | |
| 459 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_FIN)); | |
| 460 MockWrite writes[] = { | |
| 461 CreateMockWrite(*req, 0), CreateMockWrite(*data_frame, 3), | |
| 462 }; | |
| 463 | |
| 464 scoped_ptr<SpdySerializedFrame> resp( | |
| 465 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); | |
| 466 scoped_ptr<SpdySerializedFrame> response_body_frame1( | |
| 467 spdy_util_.ConstructSpdyBodyFrame(1, false)); | |
| 468 scoped_ptr<SpdySerializedFrame> response_body_frame2( | |
| 469 spdy_util_.ConstructSpdyBodyFrame(1, true)); | |
| 470 | |
| 471 MockRead reads[] = { | |
| 472 CreateMockRead(*resp, 1), | |
| 473 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause. | |
| 474 CreateMockRead(*response_body_frame1, 4), | |
| 475 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause. | |
| 476 CreateMockRead(*response_body_frame2, 6), | |
| 477 MockRead(ASYNC, 0, 7), | |
| 478 }; | |
| 479 | |
| 480 HostPortPair host_port_pair("www.example.org", 443); | |
| 481 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | |
| 482 PRIVACY_MODE_DISABLED); | |
| 483 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); | |
| 484 | |
| 485 scoped_ptr<BidirectionalStreamRequestInfo> request_info( | |
| 486 new BidirectionalStreamRequestInfo); | |
| 487 request_info->method = "POST"; | |
| 488 request_info->url = GURL("https://www.example.org/"); | |
| 489 request_info->priority = LOWEST; | |
| 490 request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, | |
| 491 base::SizeTToString(kBodyDataSize * 3)); | |
| 492 | |
| 493 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); | |
| 494 MockTimer* timer = new MockTimer(); | |
| 495 scoped_ptr<TestDelegateBase> delegate(new TestDelegateBase( | |
| 496 read_buffer.get(), kReadBufferSize, make_scoped_ptr(timer))); | |
| 497 delegate->set_do_not_start_read(true); | |
| 498 delegate->Start(std::move(request_info), http_session_.get()); | |
| 499 // Send the request and receive response headers. | |
| 500 sequenced_data_->RunUntilPaused(); | |
| 501 EXPECT_FALSE(timer->IsRunning()); | |
| 502 | |
| 503 scoped_refptr<StringIOBuffer> buf( | |
| 504 new StringIOBuffer(std::string(kBodyData, kBodyDataSize))); | |
| 505 // Send a DATA frame. | |
| 506 delegate->SendData(buf.get(), buf->size(), true); | |
| 507 // ReadData and it should return asynchronously because no data is buffered. | |
|
mmenke
2016/04/14 15:38:20
The grammar on this sentence needs to be fixed - I
xunjieli
2016/04/14 18:57:06
Done.
| |
| 508 int rv = delegate->ReadData(); | |
| 509 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 510 sequenced_data_->Resume(); | |
| 511 sequenced_data_->RunUntilPaused(); | |
|
mmenke
2016/04/14 15:38:20
Think the reason for this pause should probably be
xunjieli
2016/04/14 18:57:06
Done.
| |
| 512 timer->Fire(); | |
| 513 base::RunLoop().RunUntilIdle(); | |
|
mmenke
2016/04/14 15:38:20
Can we just run until the delegate's OnReadComplet
xunjieli
2016/04/14 18:57:06
Can we handle it in a separate CL? All tests in th
mmenke
2016/04/14 19:04:13
Sure, makes sense.
| |
| 514 EXPECT_EQ(1, delegate->on_data_read_count()); | |
| 515 | |
| 516 sequenced_data_->Resume(); | |
|
mmenke
2016/04/14 15:38:20
Is this pause actually needed?
xunjieli
2016/04/14 18:57:05
Yes, we need this to be between first and second D
| |
| 517 base::RunLoop().RunUntilIdle(); | |
|
mmenke
2016/04/14 15:38:20
Why don't you need to manually fire the timer agai
xunjieli
2016/04/14 18:57:06
The timer is stopped in BidirectionalStreamSpdyImp
| |
| 518 // Read completes synchronously. | |
| 519 rv = delegate->ReadData(); | |
| 520 EXPECT_EQ(kUploadDataSize, rv); | |
| 521 | |
| 522 EXPECT_EQ("200", delegate->response_headers().find(":status")->second); | |
| 523 EXPECT_EQ(1, delegate->on_data_read_count()); | |
| 524 EXPECT_EQ(1, delegate->on_data_sent_count()); | |
| 525 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); | |
| 526 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), | |
| 527 delegate->GetTotalSentBytes()); | |
| 528 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), | |
| 529 delegate->GetTotalReceivedBytes()); | |
| 530 | |
| 531 TestNetLogEntry::List entries; | |
| 532 net_log_.GetEntries(&entries); | |
| 533 // Sent bytes. Sending data is always asynchronous. | |
| 534 size_t index = ExpectLogContainsSomewhere( | |
| 535 entries, 0, NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT, | |
| 536 NetLog::PHASE_NONE); | |
| 537 TestNetLogEntry entry = entries[index]; | |
| 538 EXPECT_EQ(NetLog::SOURCE_BIDIRECTIONAL_STREAM, entry.source.type); | |
| 539 // Received bytes for asynchronous read. | |
| 540 index = ExpectLogContainsSomewhere( | |
| 541 entries, index, NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, | |
| 542 NetLog::PHASE_NONE); | |
| 543 entry = entries[index]; | |
| 544 EXPECT_EQ(NetLog::SOURCE_BIDIRECTIONAL_STREAM, entry.source.type); | |
| 545 // Received bytes for synchronous read. | |
| 546 index = ExpectLogContainsSomewhere( | |
| 547 entries, index, NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, | |
| 548 NetLog::PHASE_NONE); | |
| 549 entry = entries[index]; | |
| 550 EXPECT_EQ(NetLog::SOURCE_BIDIRECTIONAL_STREAM, entry.source.type); | |
| 551 } | |
| 552 | |
| 447 TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) { | 553 TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) { |
| 448 BufferedSpdyFramer framer(spdy_util_.spdy_version()); | 554 BufferedSpdyFramer framer(spdy_util_.spdy_version()); |
| 449 | 555 |
| 450 scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( | 556 scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( |
| 451 "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0)); | 557 "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0)); |
| 452 scoped_ptr<SpdySerializedFrame> data_frame1( | 558 scoped_ptr<SpdySerializedFrame> data_frame1( |
| 453 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); | 559 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| 454 scoped_ptr<SpdySerializedFrame> data_frame2( | 560 scoped_ptr<SpdySerializedFrame> data_frame2( |
| 455 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); | 561 framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); |
| 456 scoped_ptr<SpdySerializedFrame> data_frame3( | 562 scoped_ptr<SpdySerializedFrame> data_frame3( |
| (...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1261 http_session_->http_server_properties()->GetAlternativeServices( | 1367 http_session_->http_server_properties()->GetAlternativeServices( |
| 1262 host_port_pair); | 1368 host_port_pair); |
| 1263 ASSERT_EQ(1u, alternative_service_vector.size()); | 1369 ASSERT_EQ(1u, alternative_service_vector.size()); |
| 1264 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoQUIC1SPDY3), | 1370 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoQUIC1SPDY3), |
| 1265 alternative_service_vector[0].protocol); | 1371 alternative_service_vector[0].protocol); |
| 1266 EXPECT_EQ("www.example.org", alternative_service_vector[0].host); | 1372 EXPECT_EQ("www.example.org", alternative_service_vector[0].host); |
| 1267 EXPECT_EQ(443, alternative_service_vector[0].port); | 1373 EXPECT_EQ(443, alternative_service_vector[0].port); |
| 1268 } | 1374 } |
| 1269 | 1375 |
| 1270 } // namespace net | 1376 } // namespace net |
| OLD | NEW |