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 <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 std::unique_ptr<base::Timer> timer) | 51 std::unique_ptr<base::Timer> timer) |
52 : read_buf_(read_buf), | 52 : read_buf_(read_buf), |
53 read_buf_len_(read_buf_len), | 53 read_buf_len_(read_buf_len), |
54 timer_(std::move(timer)), | 54 timer_(std::move(timer)), |
55 loop_(nullptr), | 55 loop_(nullptr), |
56 error_(OK), | 56 error_(OK), |
57 on_data_read_count_(0), | 57 on_data_read_count_(0), |
58 on_data_sent_count_(0), | 58 on_data_sent_count_(0), |
59 do_not_start_read_(false), | 59 do_not_start_read_(false), |
60 run_until_completion_(false), | 60 run_until_completion_(false), |
61 not_expect_callback_(false) {} | 61 not_expect_callback_(false), |
| 62 disable_auto_flush_(false) {} |
62 | 63 |
63 ~TestDelegateBase() override {} | 64 ~TestDelegateBase() override {} |
64 | 65 |
65 void OnHeadersSent() override { CHECK(!not_expect_callback_); } | 66 void OnStreamReady() override { |
| 67 if (callback_.is_null()) |
| 68 return; |
| 69 callback_.Run(OK); |
| 70 } |
66 | 71 |
67 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override { | 72 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override { |
68 CHECK(!not_expect_callback_); | 73 CHECK(!not_expect_callback_); |
69 | 74 |
70 response_headers_ = response_headers; | 75 response_headers_ = response_headers; |
71 if (!do_not_start_read_) | 76 if (!do_not_start_read_) |
72 StartOrContinueReading(); | 77 StartOrContinueReading(); |
73 } | 78 } |
74 | 79 |
75 void OnDataRead(int bytes_read) override { | 80 void OnDataRead(int bytes_read) override { |
(...skipping 23 matching lines...) Expand all Loading... |
99 void OnFailed(int error) override { | 104 void OnFailed(int error) override { |
100 CHECK(!not_expect_callback_); | 105 CHECK(!not_expect_callback_); |
101 CHECK_EQ(OK, error_); | 106 CHECK_EQ(OK, error_); |
102 CHECK_NE(OK, error); | 107 CHECK_NE(OK, error); |
103 | 108 |
104 error_ = error; | 109 error_ = error; |
105 if (run_until_completion_) | 110 if (run_until_completion_) |
106 loop_->Quit(); | 111 loop_->Quit(); |
107 } | 112 } |
108 | 113 |
| 114 void DisableAutoFlush() { disable_auto_flush_ = true; } |
| 115 |
109 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info, | 116 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info, |
110 HttpNetworkSession* session) { | 117 HttpNetworkSession* session) { |
111 stream_.reset(new BidirectionalStream(std::move(request_info), session, | 118 stream_.reset(new BidirectionalStream(std::move(request_info), session, |
112 this, std::move(timer_))); | 119 false, this, std::move(timer_))); |
113 if (run_until_completion_) | 120 if (run_until_completion_) |
114 loop_->Run(); | 121 loop_->Run(); |
115 } | 122 } |
| 123 |
| 124 void Start(std::unique_ptr<BidirectionalStreamRequestInfo> request_info, |
| 125 HttpNetworkSession* session, |
| 126 const CompletionCallback& cb) { |
| 127 callback_ = cb; |
| 128 stream_.reset(new BidirectionalStream(std::move(request_info), session, |
| 129 disable_auto_flush_, this, |
| 130 std::move(timer_))); |
| 131 if (run_until_completion_) |
| 132 loop_->Run(); |
| 133 } |
116 | 134 |
117 void SendData(IOBuffer* data, int length, bool end_of_stream) { | 135 void SendData(IOBuffer* data, int length, bool end_of_stream) { |
118 not_expect_callback_ = true; | 136 not_expect_callback_ = true; |
119 stream_->SendData(data, length, end_of_stream); | 137 stream_->SendData(data, length, end_of_stream); |
120 not_expect_callback_ = false; | 138 not_expect_callback_ = false; |
121 } | 139 } |
122 | 140 |
| 141 void SendvData(const std::vector<IOBuffer*>& data, |
| 142 const std::vector<int>& length, |
| 143 bool end_of_stream) { |
| 144 not_expect_callback_ = true; |
| 145 stream_->SendvData(data, length, end_of_stream); |
| 146 not_expect_callback_ = false; |
| 147 } |
| 148 |
123 // Starts or continues reading data from |stream_| until no more bytes | 149 // Starts or continues reading data from |stream_| until no more bytes |
124 // can be read synchronously. | 150 // can be read synchronously. |
125 void StartOrContinueReading() { | 151 void StartOrContinueReading() { |
126 int rv = ReadData(); | 152 int rv = ReadData(); |
127 while (rv > 0) { | 153 while (rv > 0) { |
128 rv = ReadData(); | 154 rv = ReadData(); |
129 } | 155 } |
130 if (run_until_completion_ && rv == 0) | 156 if (run_until_completion_ && rv == 0) |
131 loop_->Quit(); | 157 loop_->Quit(); |
132 } | 158 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 SpdyHeaderBlock response_headers_; | 213 SpdyHeaderBlock response_headers_; |
188 SpdyHeaderBlock trailers_; | 214 SpdyHeaderBlock trailers_; |
189 int error_; | 215 int error_; |
190 int on_data_read_count_; | 216 int on_data_read_count_; |
191 int on_data_sent_count_; | 217 int on_data_sent_count_; |
192 bool do_not_start_read_; | 218 bool do_not_start_read_; |
193 bool run_until_completion_; | 219 bool run_until_completion_; |
194 // This is to ensure that delegate callback is not invoked synchronously when | 220 // This is to ensure that delegate callback is not invoked synchronously when |
195 // calling into |stream_|. | 221 // calling into |stream_|. |
196 bool not_expect_callback_; | 222 bool not_expect_callback_; |
| 223 bool disable_auto_flush_; |
197 | 224 |
| 225 CompletionCallback callback_; |
198 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); | 226 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); |
199 }; | 227 }; |
200 | 228 |
201 // A delegate that deletes the stream in a particular callback. | 229 // A delegate that deletes the stream in a particular callback. |
202 class CancelOrDeleteStreamDelegate : public TestDelegateBase { | 230 class CancelOrDeleteStreamDelegate : public TestDelegateBase { |
203 public: | 231 public: |
204 // Specifies in which callback the stream can be deleted. | 232 // Specifies in which callback the stream can be deleted. |
205 enum Phase { | 233 enum Phase { |
206 ON_HEADERS_RECEIVED, | 234 ON_HEADERS_RECEIVED, |
207 ON_DATA_READ, | 235 ON_DATA_READ, |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 EXPECT_EQ("200", delegate->response_headers().find(":status")->second); | 685 EXPECT_EQ("200", delegate->response_headers().find(":status")->second); |
658 EXPECT_EQ(2, delegate->on_data_read_count()); | 686 EXPECT_EQ(2, delegate->on_data_read_count()); |
659 EXPECT_EQ(3, delegate->on_data_sent_count()); | 687 EXPECT_EQ(3, delegate->on_data_sent_count()); |
660 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); | 688 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); |
661 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), | 689 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), |
662 delegate->GetTotalSentBytes()); | 690 delegate->GetTotalSentBytes()); |
663 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), | 691 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), |
664 delegate->GetTotalReceivedBytes()); | 692 delegate->GetTotalReceivedBytes()); |
665 } | 693 } |
666 | 694 |
| 695 TEST_F(BidirectionalStreamTest, TestCoalesceSmallDataBuffers) { |
| 696 BufferedSpdyFramer framer(spdy_util_.spdy_version()); |
| 697 |
| 698 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( |
| 699 "https://www.example.org", 1, kBodyDataSize * 1, LOWEST, nullptr, 0)); |
| 700 std::string body_data = "some really long piece of data"; |
| 701 std::unique_ptr<SpdySerializedFrame> data_frame1(framer.CreateDataFrame( |
| 702 1, body_data.c_str(), body_data.size(), DATA_FLAG_FIN)); |
| 703 MockWrite writes[] = { |
| 704 CreateMockWrite(*req, 0), CreateMockWrite(*data_frame1, 1), |
| 705 }; |
| 706 |
| 707 std::unique_ptr<SpdySerializedFrame> resp( |
| 708 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); |
| 709 std::unique_ptr<SpdySerializedFrame> response_body_frame1( |
| 710 spdy_util_.ConstructSpdyBodyFrame(1, true)); |
| 711 MockRead reads[] = { |
| 712 CreateMockRead(*resp, 2), |
| 713 MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause. |
| 714 CreateMockRead(*response_body_frame1, 4), MockRead(ASYNC, 0, 5), |
| 715 }; |
| 716 |
| 717 HostPortPair host_port_pair("www.example.org", 443); |
| 718 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), |
| 719 PRIVACY_MODE_DISABLED); |
| 720 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); |
| 721 |
| 722 std::unique_ptr<BidirectionalStreamRequestInfo> request_info( |
| 723 new BidirectionalStreamRequestInfo); |
| 724 request_info->method = "POST"; |
| 725 request_info->url = GURL("https://www.example.org/"); |
| 726 request_info->priority = LOWEST; |
| 727 request_info->extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, |
| 728 base::SizeTToString(kBodyDataSize * 1)); |
| 729 |
| 730 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); |
| 731 MockTimer* timer = new MockTimer(); |
| 732 std::unique_ptr<TestDelegateBase> delegate(new TestDelegateBase( |
| 733 read_buffer.get(), kReadBufferSize, base::WrapUnique(timer))); |
| 734 delegate->set_do_not_start_read(true); |
| 735 delegate->DisableAutoFlush(); |
| 736 TestCompletionCallback callback; |
| 737 delegate->Start(std::move(request_info), http_session_.get(), |
| 738 callback.callback()); |
| 739 // Wait until the stream is ready. |
| 740 callback.WaitForResult(); |
| 741 // Send a DATA frame. |
| 742 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(body_data.substr(0, 5))); |
| 743 scoped_refptr<StringIOBuffer> buf2( |
| 744 new StringIOBuffer(body_data.substr(5, body_data.size() - 5))); |
| 745 delegate->SendvData({buf.get(), buf2.get()}, {buf->size(), buf2->size()}, |
| 746 true); |
| 747 sequenced_data_->RunUntilPaused(); // OnHeadersReceived. |
| 748 // ReadData and it should return asynchronously because no data is buffered. |
| 749 EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData()); |
| 750 sequenced_data_->Resume(); |
| 751 base::RunLoop().RunUntilIdle(); |
| 752 EXPECT_EQ(1, delegate->on_data_sent_count()); |
| 753 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 754 |
| 755 EXPECT_EQ("200", delegate->response_headers().find(":status")->second); |
| 756 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 757 EXPECT_EQ(1, delegate->on_data_sent_count()); |
| 758 EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); |
| 759 EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), |
| 760 delegate->GetTotalSentBytes()); |
| 761 EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), |
| 762 delegate->GetTotalReceivedBytes()); |
| 763 } |
| 764 |
667 // Tests that BidirectionalStreamSpdyImpl::OnClose will complete any remaining | 765 // Tests that BidirectionalStreamSpdyImpl::OnClose will complete any remaining |
668 // read even if the read queue is empty. | 766 // read even if the read queue is empty. |
669 TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) { | 767 TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) { |
670 std::unique_ptr<SpdySerializedFrame> req( | 768 std::unique_ptr<SpdySerializedFrame> req( |
671 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST)); | 769 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST)); |
672 // Empty DATA frame with an END_STREAM flag. | 770 // Empty DATA frame with an END_STREAM flag. |
673 std::unique_ptr<SpdySerializedFrame> end_stream( | 771 std::unique_ptr<SpdySerializedFrame> end_stream( |
674 spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true)); | 772 spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true)); |
675 | 773 |
676 MockWrite writes[] = {CreateMockWrite(*req.get(), 0)}; | 774 MockWrite writes[] = {CreateMockWrite(*req.get(), 0)}; |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 AlternativeServiceVector alternative_service_vector = | 1472 AlternativeServiceVector alternative_service_vector = |
1375 http_session_->http_server_properties()->GetAlternativeServices(server); | 1473 http_session_->http_server_properties()->GetAlternativeServices(server); |
1376 ASSERT_EQ(1u, alternative_service_vector.size()); | 1474 ASSERT_EQ(1u, alternative_service_vector.size()); |
1377 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoQUIC1SPDY3), | 1475 EXPECT_EQ(AlternateProtocolFromNextProto(kProtoQUIC1SPDY3), |
1378 alternative_service_vector[0].protocol); | 1476 alternative_service_vector[0].protocol); |
1379 EXPECT_EQ("www.example.org", alternative_service_vector[0].host); | 1477 EXPECT_EQ("www.example.org", alternative_service_vector[0].host); |
1380 EXPECT_EQ(443, alternative_service_vector[0].port); | 1478 EXPECT_EQ(443, alternative_service_vector[0].port); |
1381 } | 1479 } |
1382 | 1480 |
1383 } // namespace net | 1481 } // namespace net |
OLD | NEW |