| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/spdy/bidirectional_stream_spdy_impl.h" | 5 #include "net/spdy/bidirectional_stream_spdy_impl.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 bool do_not_start_read_; | 227 bool do_not_start_read_; |
| 228 bool run_until_completion_; | 228 bool run_until_completion_; |
| 229 bool not_expect_callback_; | 229 bool not_expect_callback_; |
| 230 bool on_failed_called_; | 230 bool on_failed_called_; |
| 231 | 231 |
| 232 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); | 232 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); |
| 233 }; | 233 }; |
| 234 | 234 |
| 235 } // namespace | 235 } // namespace |
| 236 | 236 |
| 237 class BidirectionalStreamSpdyImplTest : public testing::Test { | 237 class BidirectionalStreamSpdyImplTest : public testing::TestWithParam<bool> { |
| 238 public: | 238 public: |
| 239 BidirectionalStreamSpdyImplTest() | 239 BidirectionalStreamSpdyImplTest() |
| 240 : default_url_(kDefaultUrl), | 240 : default_url_(kDefaultUrl), |
| 241 host_port_pair_(HostPortPair::FromURL(default_url_)), | 241 host_port_pair_(HostPortPair::FromURL(default_url_)), |
| 242 key_(host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED), | 242 key_(host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED), |
| 243 ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { | 243 ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { |
| 244 ssl_data_.next_proto = kProtoHTTP2; | 244 ssl_data_.next_proto = kProtoHTTP2; |
| 245 ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); | 245 ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); |
| 246 } | 246 } |
| 247 | 247 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 EXPECT_EQ(0, delegate->on_data_read_count()); | 425 EXPECT_EQ(0, delegate->on_data_read_count()); |
| 426 EXPECT_EQ(0, delegate->on_data_sent_count()); | 426 EXPECT_EQ(0, delegate->on_data_sent_count()); |
| 427 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); | 427 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); |
| 428 // BidirectionalStreamSpdyStreamJob does not count the bytes sent for |rst| | 428 // BidirectionalStreamSpdyStreamJob does not count the bytes sent for |rst| |
| 429 // because it is sent after SpdyStream::Delegate::OnClose is called. | 429 // because it is sent after SpdyStream::Delegate::OnClose is called. |
| 430 EXPECT_EQ(CountWriteBytes(writes, 1), delegate->GetTotalSentBytes()); | 430 EXPECT_EQ(CountWriteBytes(writes, 1), delegate->GetTotalSentBytes()); |
| 431 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), | 431 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), |
| 432 delegate->GetTotalReceivedBytes()); | 432 delegate->GetTotalReceivedBytes()); |
| 433 } | 433 } |
| 434 | 434 |
| 435 INSTANTIATE_TEST_CASE_P(BidirectionalStreamSpdyImplTests, |
| 436 BidirectionalStreamSpdyImplTest, |
| 437 ::testing::Bool()); |
| 438 |
| 439 // Tests that when received RST_STREAM with NO_ERROR, BidirectionalStream does |
| 440 // not crash when processing pending writes. See crbug.com/650438. |
| 441 TEST_P(BidirectionalStreamSpdyImplTest, RstWithNoErrorBeforeSendIsComplete) { |
| 442 bool is_test_sendv = GetParam(); |
| 443 SpdySerializedFrame req(spdy_util_.ConstructSpdyPost( |
| 444 kDefaultUrl, 1, kBodyDataSize * 3, LOW, nullptr, 0)); |
| 445 MockWrite writes[] = {CreateMockWrite(req, 0)}; |
| 446 |
| 447 SpdySerializedFrame resp(spdy_util_.ConstructSpdyPostReply(nullptr, 0)); |
| 448 SpdySerializedFrame rst( |
| 449 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_NO_ERROR)); |
| 450 MockRead reads[] = {CreateMockRead(resp, 1), |
| 451 MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause. |
| 452 CreateMockRead(rst, 3), MockRead(ASYNC, 0, 4)}; |
| 453 |
| 454 InitSession(reads, arraysize(reads), writes, arraysize(writes)); |
| 455 |
| 456 BidirectionalStreamRequestInfo request_info; |
| 457 request_info.method = "POST"; |
| 458 request_info.url = default_url_; |
| 459 request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, |
| 460 base::SizeTToString(kBodyDataSize * 3)); |
| 461 |
| 462 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); |
| 463 std::unique_ptr<TestDelegateBase> delegate( |
| 464 new TestDelegateBase(session_, read_buffer.get(), kReadBufferSize)); |
| 465 delegate->SetRunUntilCompletion(true); |
| 466 delegate->Start(&request_info, net_log_.bound()); |
| 467 sequenced_data_->RunUntilPaused(); |
| 468 // Make a write pending before receiving RST_STREAM. |
| 469 scoped_refptr<StringIOBuffer> write_buffer( |
| 470 new StringIOBuffer(std::string(kBodyData, kBodyDataSize))); |
| 471 delegate->SendData(write_buffer.get(), write_buffer->size(), false); |
| 472 sequenced_data_->Resume(); |
| 473 base::RunLoop().RunUntilIdle(); |
| 474 |
| 475 // Make sure OnClose() without an error completes any pending write(). |
| 476 EXPECT_EQ(1, delegate->on_data_sent_count()); |
| 477 EXPECT_FALSE(delegate->on_failed_called()); |
| 478 |
| 479 if (is_test_sendv) { |
| 480 std::vector<scoped_refptr<IOBuffer>> three_buffers = { |
| 481 write_buffer.get(), write_buffer.get(), write_buffer.get()}; |
| 482 std::vector<int> three_lengths = { |
| 483 write_buffer->size(), write_buffer->size(), write_buffer->size()}; |
| 484 delegate->SendvData(three_buffers, three_lengths, /*end_of_stream=*/true); |
| 485 base::RunLoop().RunUntilIdle(); |
| 486 } else { |
| 487 for (size_t j = 0; j < 3; j++) { |
| 488 delegate->SendData(write_buffer.get(), write_buffer->size(), |
| 489 /*end_of_stream=*/j == 2); |
| 490 base::RunLoop().RunUntilIdle(); |
| 491 } |
| 492 } |
| 493 delegate->WaitUntilCompletion(); |
| 494 LoadTimingInfo load_timing_info; |
| 495 EXPECT_TRUE(delegate->GetLoadTimingInfo(&load_timing_info)); |
| 496 TestLoadTimingNotReused(load_timing_info); |
| 497 |
| 498 EXPECT_THAT(delegate->error(), IsError(OK)); |
| 499 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 500 EXPECT_EQ(is_test_sendv ? 2 : 4, delegate->on_data_sent_count()); |
| 501 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); |
| 502 EXPECT_EQ(CountWriteBytes(writes, 1), delegate->GetTotalSentBytes()); |
| 503 // Should not count RST stream. |
| 504 EXPECT_EQ(CountReadBytes(reads, arraysize(reads) - 2), |
| 505 delegate->GetTotalReceivedBytes()); |
| 506 |
| 507 // Now call SendData again should produce an error because end of stream |
| 508 // flag has been written. |
| 509 if (is_test_sendv) { |
| 510 std::vector<scoped_refptr<IOBuffer>> buffer = {write_buffer.get()}; |
| 511 std::vector<int> buffer_size = {write_buffer->size()}; |
| 512 delegate->SendvData(buffer, buffer_size, true); |
| 513 } else { |
| 514 delegate->SendData(write_buffer.get(), write_buffer->size(), true); |
| 515 } |
| 516 base::RunLoop().RunUntilIdle(); |
| 517 EXPECT_THAT(delegate->error(), IsError(ERR_UNEXPECTED)); |
| 518 EXPECT_TRUE(delegate->on_failed_called()); |
| 519 EXPECT_EQ(is_test_sendv ? 2 : 4, delegate->on_data_sent_count()); |
| 520 } |
| 521 |
| 435 } // namespace net | 522 } // namespace net |
| OLD | NEW |