| 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/quic/bidirectional_stream_quic_impl.h" | 5 #include "net/quic/bidirectional_stream_quic_impl.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 int read_buf_len, | 61 int read_buf_len, |
| 62 std::unique_ptr<base::Timer> timer) | 62 std::unique_ptr<base::Timer> timer) |
| 63 : read_buf_(read_buf), | 63 : read_buf_(read_buf), |
| 64 read_buf_len_(read_buf_len), | 64 read_buf_len_(read_buf_len), |
| 65 timer_(std::move(timer)), | 65 timer_(std::move(timer)), |
| 66 loop_(nullptr), | 66 loop_(nullptr), |
| 67 error_(OK), | 67 error_(OK), |
| 68 on_data_read_count_(0), | 68 on_data_read_count_(0), |
| 69 on_data_sent_count_(0), | 69 on_data_sent_count_(0), |
| 70 not_expect_callback_(false), | 70 not_expect_callback_(false), |
| 71 disable_auto_flush_(false) { | 71 send_request_headers_automatically_(true) { |
| 72 loop_.reset(new base::RunLoop); | 72 loop_.reset(new base::RunLoop); |
| 73 } | 73 } |
| 74 | 74 |
| 75 ~TestDelegateBase() override {} | 75 ~TestDelegateBase() override {} |
| 76 | 76 |
| 77 void OnStreamReady() override { | 77 void OnStreamReady(bool request_headers_sent) override { |
| 78 EXPECT_EQ(send_request_headers_automatically_, request_headers_sent); |
| 78 CHECK(!not_expect_callback_); | 79 CHECK(!not_expect_callback_); |
| 79 loop_->Quit(); | 80 loop_->Quit(); |
| 80 } | 81 } |
| 81 | 82 |
| 82 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override { | 83 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override { |
| 83 CHECK(!not_expect_callback_); | 84 CHECK(!not_expect_callback_); |
| 84 | 85 |
| 85 response_headers_ = response_headers; | 86 response_headers_ = response_headers; |
| 86 loop_->Quit(); | 87 loop_->Quit(); |
| 87 } | 88 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 115 CHECK_EQ(OK, error_); | 116 CHECK_EQ(OK, error_); |
| 116 CHECK_NE(OK, error); | 117 CHECK_NE(OK, error); |
| 117 | 118 |
| 118 error_ = error; | 119 error_ = error; |
| 119 loop_->Quit(); | 120 loop_->Quit(); |
| 120 } | 121 } |
| 121 | 122 |
| 122 void Start(const BidirectionalStreamRequestInfo* request_info, | 123 void Start(const BidirectionalStreamRequestInfo* request_info, |
| 123 const BoundNetLog& net_log, | 124 const BoundNetLog& net_log, |
| 124 const base::WeakPtr<QuicChromiumClientSession> session) { | 125 const base::WeakPtr<QuicChromiumClientSession> session) { |
| 125 stream_job_.reset(new BidirectionalStreamQuicImpl(session)); | 126 stream_.reset(new BidirectionalStreamQuicImpl(session)); |
| 126 stream_job_->Start(request_info, net_log, disable_auto_flush_, this, | 127 stream_->Start(request_info, net_log, send_request_headers_automatically_, |
| 127 nullptr); | 128 this, nullptr); |
| 128 } | 129 } |
| 129 | 130 |
| 131 void SendRequestHeaders() { stream_->SendRequestHeaders(); } |
| 132 |
| 130 void SendData(const scoped_refptr<IOBuffer>& data, | 133 void SendData(const scoped_refptr<IOBuffer>& data, |
| 131 int length, | 134 int length, |
| 132 bool end_of_stream) { | 135 bool end_of_stream) { |
| 133 not_expect_callback_ = true; | 136 not_expect_callback_ = true; |
| 134 stream_job_->SendData(data, length, end_of_stream); | 137 stream_->SendData(data, length, end_of_stream); |
| 135 not_expect_callback_ = false; | 138 not_expect_callback_ = false; |
| 136 } | 139 } |
| 137 | 140 |
| 138 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& data, | 141 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& data, |
| 139 const std::vector<int>& lengths, | 142 const std::vector<int>& lengths, |
| 140 bool end_of_stream) { | 143 bool end_of_stream) { |
| 141 not_expect_callback_ = true; | 144 not_expect_callback_ = true; |
| 142 stream_job_->SendvData(data, lengths, end_of_stream); | 145 stream_->SendvData(data, lengths, end_of_stream); |
| 143 not_expect_callback_ = false; | 146 not_expect_callback_ = false; |
| 144 } | 147 } |
| 145 | 148 |
| 146 // Waits until next Delegate callback. | 149 // Waits until next Delegate callback. |
| 147 void WaitUntilNextCallback() { | 150 void WaitUntilNextCallback() { |
| 148 loop_->Run(); | 151 loop_->Run(); |
| 149 loop_.reset(new base::RunLoop); | 152 loop_.reset(new base::RunLoop); |
| 150 } | 153 } |
| 151 | 154 |
| 152 // Calls ReadData on the |stream_| and updates |data_received_|. | 155 // Calls ReadData on the |stream_| and updates |data_received_|. |
| 153 int ReadData(const CompletionCallback& callback) { | 156 int ReadData(const CompletionCallback& callback) { |
| 154 not_expect_callback_ = true; | 157 not_expect_callback_ = true; |
| 155 int rv = stream_job_->ReadData(read_buf_.get(), read_buf_len_); | 158 int rv = stream_->ReadData(read_buf_.get(), read_buf_len_); |
| 156 not_expect_callback_ = false; | 159 not_expect_callback_ = false; |
| 157 if (rv > 0) | 160 if (rv > 0) |
| 158 data_received_.append(read_buf_->data(), rv); | 161 data_received_.append(read_buf_->data(), rv); |
| 159 if (rv == ERR_IO_PENDING) | 162 if (rv == ERR_IO_PENDING) |
| 160 callback_ = callback; | 163 callback_ = callback; |
| 161 return rv; | 164 return rv; |
| 162 } | 165 } |
| 163 | 166 |
| 164 // Cancels |stream_|. | 167 // Cancels |stream_|. |
| 165 void CancelStream() { stream_job_->Cancel(); } | 168 void CancelStream() { stream_->Cancel(); } |
| 166 | 169 |
| 167 NextProto GetProtocol() const { return stream_job_->GetProtocol(); } | 170 NextProto GetProtocol() const { return stream_->GetProtocol(); } |
| 168 | 171 |
| 169 int64_t GetTotalReceivedBytes() const { | 172 int64_t GetTotalReceivedBytes() const { |
| 170 return stream_job_->GetTotalReceivedBytes(); | 173 return stream_->GetTotalReceivedBytes(); |
| 171 } | 174 } |
| 172 | 175 |
| 173 int64_t GetTotalSentBytes() const { return stream_job_->GetTotalSentBytes(); } | 176 int64_t GetTotalSentBytes() const { return stream_->GetTotalSentBytes(); } |
| 174 | 177 |
| 175 void DisableAutoFlush() { disable_auto_flush_ = true; } | 178 void DoNotSendRequestHeadersAutomatically() { |
| 179 send_request_headers_automatically_ = false; |
| 180 } |
| 176 | 181 |
| 177 // Const getters for internal states. | 182 // Const getters for internal states. |
| 178 const std::string& data_received() const { return data_received_; } | 183 const std::string& data_received() const { return data_received_; } |
| 179 int error() const { return error_; } | 184 int error() const { return error_; } |
| 180 const SpdyHeaderBlock& response_headers() const { return response_headers_; } | 185 const SpdyHeaderBlock& response_headers() const { return response_headers_; } |
| 181 const SpdyHeaderBlock& trailers() const { return trailers_; } | 186 const SpdyHeaderBlock& trailers() const { return trailers_; } |
| 182 int on_data_read_count() const { return on_data_read_count_; } | 187 int on_data_read_count() const { return on_data_read_count_; } |
| 183 int on_data_sent_count() const { return on_data_sent_count_; } | 188 int on_data_sent_count() const { return on_data_sent_count_; } |
| 184 | 189 |
| 185 protected: | 190 protected: |
| 186 // Quits |loop_|. | 191 // Quits |loop_|. |
| 187 void QuitLoop() { loop_->Quit(); } | 192 void QuitLoop() { loop_->Quit(); } |
| 188 | 193 |
| 189 // Deletes |stream_|. | 194 // Deletes |stream_|. |
| 190 void DeleteStream() { stream_job_.reset(); } | 195 void DeleteStream() { stream_.reset(); } |
| 191 | 196 |
| 192 private: | 197 private: |
| 193 std::unique_ptr<BidirectionalStreamQuicImpl> stream_job_; | 198 std::unique_ptr<BidirectionalStreamQuicImpl> stream_; |
| 194 scoped_refptr<IOBuffer> read_buf_; | 199 scoped_refptr<IOBuffer> read_buf_; |
| 195 int read_buf_len_; | 200 int read_buf_len_; |
| 196 std::unique_ptr<base::Timer> timer_; | 201 std::unique_ptr<base::Timer> timer_; |
| 197 std::string data_received_; | 202 std::string data_received_; |
| 198 std::unique_ptr<base::RunLoop> loop_; | 203 std::unique_ptr<base::RunLoop> loop_; |
| 199 SpdyHeaderBlock response_headers_; | 204 SpdyHeaderBlock response_headers_; |
| 200 SpdyHeaderBlock trailers_; | 205 SpdyHeaderBlock trailers_; |
| 201 int error_; | 206 int error_; |
| 202 int on_data_read_count_; | 207 int on_data_read_count_; |
| 203 int on_data_sent_count_; | 208 int on_data_sent_count_; |
| 204 // This is to ensure that delegate callback is not invoked synchronously when | 209 // This is to ensure that delegate callback is not invoked synchronously when |
| 205 // calling into |stream_|. | 210 // calling into |stream_|. |
| 206 bool not_expect_callback_; | 211 bool not_expect_callback_; |
| 207 CompletionCallback callback_; | 212 CompletionCallback callback_; |
| 208 bool disable_auto_flush_; | 213 bool send_request_headers_automatically_; |
| 209 | 214 |
| 210 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); | 215 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); |
| 211 }; | 216 }; |
| 212 | 217 |
| 213 // A delegate that deletes the stream in a particular callback. | 218 // A delegate that deletes the stream in a particular callback. |
| 214 class DeleteStreamDelegate : public TestDelegateBase { | 219 class DeleteStreamDelegate : public TestDelegateBase { |
| 215 public: | 220 public: |
| 216 // Specifies in which callback the stream can be deleted. | 221 // Specifies in which callback the stream can be deleted. |
| 217 enum Phase { | 222 enum Phase { |
| 218 ON_HEADERS_RECEIVED, | 223 ON_HEADERS_RECEIVED, |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 pos = ExpectLogContainsSomewhere( | 665 pos = ExpectLogContainsSomewhere( |
| 661 entries, /*min_offset=*/pos, | 666 entries, /*min_offset=*/pos, |
| 662 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS, | 667 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS, |
| 663 NetLog::PHASE_NONE); | 668 NetLog::PHASE_NONE); |
| 664 ExpectLogContainsSomewhere( | 669 ExpectLogContainsSomewhere( |
| 665 entries, /*min_offset=*/pos, | 670 entries, /*min_offset=*/pos, |
| 666 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS, | 671 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS, |
| 667 NetLog::PHASE_NONE); | 672 NetLog::PHASE_NONE); |
| 668 } | 673 } |
| 669 | 674 |
| 670 TEST_P(BidirectionalStreamQuicImplTest, CoalesceSmallBuffers) { | 675 // Tests that when request headers are not delayed, only data buffers are |
| 676 // coalesced. |
| 677 TEST_P(BidirectionalStreamQuicImplTest, CoalesceDataBuffersNotHeadersFrame) { |
| 671 SetRequest("POST", "/", DEFAULT_PRIORITY); | 678 SetRequest("POST", "/", DEFAULT_PRIORITY); |
| 672 size_t spdy_request_headers_frame_length; | 679 size_t spdy_request_headers_frame_length; |
| 673 | 680 |
| 681 const char kBody1[] = "here are some data"; |
| 682 const char kBody2[] = "data keep coming"; |
| 683 std::vector<std::string> two_writes = {kBody1, kBody2}; |
| 684 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY, |
| 685 &spdy_request_headers_frame_length)); |
| 686 AddWrite(ConstructClientMultipleDataFramesPacket(2, kIncludeVersion, !kFin, 0, |
| 687 {kBody1, kBody2})); |
| 688 // Ack server's data packet. |
| 689 AddWrite(ConstructClientAckPacket(3, 3, 1)); |
| 690 const char kBody3[] = "hello there"; |
| 691 const char kBody4[] = "another piece of small data"; |
| 692 const char kBody5[] = "really small"; |
| 693 QuicStreamOffset data_offset = strlen(kBody1) + strlen(kBody2); |
| 694 AddWrite(ConstructClientMultipleDataFramesPacket( |
| 695 4, !kIncludeVersion, kFin, data_offset, {kBody3, kBody4, kBody5})); |
| 696 |
| 697 Initialize(); |
| 698 |
| 699 BidirectionalStreamRequestInfo request; |
| 700 request.method = "POST"; |
| 701 request.url = GURL("http://www.google.com/"); |
| 702 request.end_stream_on_headers = false; |
| 703 request.priority = DEFAULT_PRIORITY; |
| 704 |
| 705 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); |
| 706 std::unique_ptr<TestDelegateBase> delegate( |
| 707 new TestDelegateBase(read_buffer.get(), kReadBufferSize)); |
| 708 delegate->DoNotSendRequestHeadersAutomatically(); |
| 709 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr()); |
| 710 delegate->WaitUntilNextCallback(); // OnStreamReady |
| 711 |
| 712 // Sends request headers separately, which causes them to be sent in a |
| 713 // separate packet. |
| 714 delegate->SendRequestHeaders(); |
| 715 // Send a Data packet. |
| 716 scoped_refptr<StringIOBuffer> buf1(new StringIOBuffer(kBody1)); |
| 717 scoped_refptr<StringIOBuffer> buf2(new StringIOBuffer(kBody2)); |
| 718 |
| 719 std::vector<int> lengths = {buf1->size(), buf2->size()}; |
| 720 delegate->SendvData({buf1, buf2}, lengths, !kFin); |
| 721 delegate->WaitUntilNextCallback(); // OnDataSent |
| 722 |
| 723 // Server acks the request. |
| 724 ProcessPacket(ConstructServerAckPacket(1, 0, 0)); |
| 725 |
| 726 // Server sends the response headers. |
| 727 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200"); |
| 728 size_t spdy_response_headers_frame_length; |
| 729 QuicStreamOffset offset = 0; |
| 730 ProcessPacket(ConstructResponseHeadersPacket( |
| 731 2, !kFin, response_headers, &spdy_response_headers_frame_length, |
| 732 &offset)); |
| 733 |
| 734 delegate->WaitUntilNextCallback(); // OnHeadersReceived |
| 735 TestCompletionCallback cb; |
| 736 int rv = delegate->ReadData(cb.callback()); |
| 737 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 738 EXPECT_EQ("200", delegate->response_headers().find(":status")->second); |
| 739 const char kResponseBody[] = "Hello world!"; |
| 740 // Server sends data. |
| 741 ProcessPacket( |
| 742 ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody)); |
| 743 |
| 744 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), cb.WaitForResult()); |
| 745 |
| 746 // Send a second Data packet. |
| 747 scoped_refptr<StringIOBuffer> buf3(new StringIOBuffer(kBody3)); |
| 748 scoped_refptr<StringIOBuffer> buf4(new StringIOBuffer(kBody4)); |
| 749 scoped_refptr<StringIOBuffer> buf5(new StringIOBuffer(kBody5)); |
| 750 |
| 751 delegate->SendvData({buf3, buf4, buf5}, |
| 752 {buf3->size(), buf4->size(), buf5->size()}, kFin); |
| 753 delegate->WaitUntilNextCallback(); // OnDataSent |
| 754 |
| 755 size_t spdy_trailers_frame_length; |
| 756 SpdyHeaderBlock trailers; |
| 757 trailers["foo"] = "bar"; |
| 758 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody)); |
| 759 // Server sends trailers. |
| 760 ProcessPacket(ConstructResponseTrailersPacket( |
| 761 4, kFin, trailers, &spdy_trailers_frame_length, &offset)); |
| 762 |
| 763 delegate->WaitUntilNextCallback(); // OnTrailersReceived |
| 764 trailers.erase(kFinalOffsetHeaderKey); |
| 765 EXPECT_EQ(trailers, delegate->trailers()); |
| 766 EXPECT_EQ(OK, delegate->ReadData(cb.callback())); |
| 767 |
| 768 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 769 EXPECT_EQ(2, delegate->on_data_sent_count()); |
| 770 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol()); |
| 771 EXPECT_EQ( |
| 772 static_cast<int64_t>(spdy_request_headers_frame_length + strlen(kBody1) + |
| 773 strlen(kBody2) + strlen(kBody3) + strlen(kBody4) + |
| 774 strlen(kBody5)), |
| 775 delegate->GetTotalSentBytes()); |
| 776 EXPECT_EQ( |
| 777 static_cast<int64_t>(spdy_response_headers_frame_length + |
| 778 strlen(kResponseBody) + spdy_trailers_frame_length), |
| 779 delegate->GetTotalReceivedBytes()); |
| 780 } |
| 781 |
| 782 // Tests that when request headers are delayed, SendData triggers coalescing of |
| 783 // request headers with data buffers. |
| 784 TEST_P(BidirectionalStreamQuicImplTest, |
| 785 SendDataCoalesceDataBufferAndHeaderFrame) { |
| 786 SetRequest("POST", "/", DEFAULT_PRIORITY); |
| 787 size_t spdy_request_headers_frame_length; |
| 788 |
| 789 const char kBody1[] = "here are some data"; |
| 790 AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket( |
| 791 1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, |
| 792 {kBody1})); |
| 793 // Ack server's data packet. |
| 794 AddWrite(ConstructClientAckPacket(2, 3, 1)); |
| 795 const char kBody2[] = "really small"; |
| 796 QuicStreamOffset data_offset = strlen(kBody1); |
| 797 AddWrite(ConstructClientMultipleDataFramesPacket(3, !kIncludeVersion, kFin, |
| 798 data_offset, {kBody2})); |
| 799 |
| 800 Initialize(); |
| 801 |
| 802 BidirectionalStreamRequestInfo request; |
| 803 request.method = "POST"; |
| 804 request.url = GURL("http://www.google.com/"); |
| 805 request.end_stream_on_headers = false; |
| 806 request.priority = DEFAULT_PRIORITY; |
| 807 |
| 808 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); |
| 809 std::unique_ptr<TestDelegateBase> delegate( |
| 810 new TestDelegateBase(read_buffer.get(), kReadBufferSize)); |
| 811 delegate->DoNotSendRequestHeadersAutomatically(); |
| 812 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr()); |
| 813 delegate->WaitUntilNextCallback(); // OnStreamReady |
| 814 |
| 815 // Send a Data packet. |
| 816 scoped_refptr<StringIOBuffer> buf1(new StringIOBuffer(kBody1)); |
| 817 |
| 818 delegate->SendData(buf1, buf1->size(), false); |
| 819 delegate->WaitUntilNextCallback(); // OnDataSent |
| 820 |
| 821 // Server acks the request. |
| 822 ProcessPacket(ConstructServerAckPacket(1, 0, 0)); |
| 823 |
| 824 // Server sends the response headers. |
| 825 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200"); |
| 826 size_t spdy_response_headers_frame_length; |
| 827 QuicStreamOffset offset = 0; |
| 828 ProcessPacket(ConstructResponseHeadersPacket( |
| 829 2, !kFin, response_headers, &spdy_response_headers_frame_length, |
| 830 &offset)); |
| 831 |
| 832 delegate->WaitUntilNextCallback(); // OnHeadersReceived |
| 833 TestCompletionCallback cb; |
| 834 int rv = delegate->ReadData(cb.callback()); |
| 835 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 836 EXPECT_EQ("200", delegate->response_headers().find(":status")->second); |
| 837 const char kResponseBody[] = "Hello world!"; |
| 838 // Server sends data. |
| 839 ProcessPacket( |
| 840 ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody)); |
| 841 |
| 842 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), cb.WaitForResult()); |
| 843 |
| 844 // Send a second Data packet. |
| 845 scoped_refptr<StringIOBuffer> buf2(new StringIOBuffer(kBody2)); |
| 846 |
| 847 delegate->SendData(buf2, buf2->size(), true); |
| 848 delegate->WaitUntilNextCallback(); // OnDataSent |
| 849 |
| 850 size_t spdy_trailers_frame_length; |
| 851 SpdyHeaderBlock trailers; |
| 852 trailers["foo"] = "bar"; |
| 853 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody)); |
| 854 // Server sends trailers. |
| 855 ProcessPacket(ConstructResponseTrailersPacket( |
| 856 4, kFin, trailers, &spdy_trailers_frame_length, &offset)); |
| 857 |
| 858 delegate->WaitUntilNextCallback(); // OnTrailersReceived |
| 859 trailers.erase(kFinalOffsetHeaderKey); |
| 860 EXPECT_EQ(trailers, delegate->trailers()); |
| 861 EXPECT_EQ(OK, delegate->ReadData(cb.callback())); |
| 862 |
| 863 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 864 EXPECT_EQ(2, delegate->on_data_sent_count()); |
| 865 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol()); |
| 866 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length + |
| 867 strlen(kBody1) + strlen(kBody2)), |
| 868 delegate->GetTotalSentBytes()); |
| 869 EXPECT_EQ( |
| 870 static_cast<int64_t>(spdy_response_headers_frame_length + |
| 871 strlen(kResponseBody) + spdy_trailers_frame_length), |
| 872 delegate->GetTotalReceivedBytes()); |
| 873 } |
| 874 |
| 875 // Tests that when request headers are delayed, SendvData triggers coalescing of |
| 876 // request headers with data buffers. |
| 877 TEST_P(BidirectionalStreamQuicImplTest, |
| 878 SendvDataCoalesceDataBuffersAndHeaderFrame) { |
| 879 SetRequest("POST", "/", DEFAULT_PRIORITY); |
| 880 size_t spdy_request_headers_frame_length; |
| 881 |
| 674 const char kBody1[] = "here are some data"; | 882 const char kBody1[] = "here are some data"; |
| 675 const char kBody2[] = "data keep coming"; | 883 const char kBody2[] = "data keep coming"; |
| 676 std::vector<std::string> two_writes = {kBody1, kBody2}; | 884 std::vector<std::string> two_writes = {kBody1, kBody2}; |
| 677 AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket( | 885 AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket( |
| 678 1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, | 886 1, !kFin, DEFAULT_PRIORITY, &spdy_request_headers_frame_length, |
| 679 two_writes)); | 887 two_writes)); |
| 680 // Ack server's data packet. | 888 // Ack server's data packet. |
| 681 AddWrite(ConstructClientAckPacket(2, 3, 1)); | 889 AddWrite(ConstructClientAckPacket(2, 3, 1)); |
| 682 const char kBody3[] = "hello there"; | 890 const char kBody3[] = "hello there"; |
| 683 const char kBody4[] = "another piece of small data"; | 891 const char kBody4[] = "another piece of small data"; |
| 684 const char kBody5[] = "really small"; | 892 const char kBody5[] = "really small"; |
| 685 QuicStreamOffset data_offset = strlen(kBody1) + strlen(kBody2); | 893 QuicStreamOffset data_offset = strlen(kBody1) + strlen(kBody2); |
| 686 AddWrite(ConstructClientMultipleDataFramesPacket( | 894 AddWrite(ConstructClientMultipleDataFramesPacket( |
| 687 3, !kIncludeVersion, kFin, data_offset, {kBody3, kBody4, kBody5})); | 895 3, !kIncludeVersion, kFin, data_offset, {kBody3, kBody4, kBody5})); |
| 688 | 896 |
| 689 Initialize(); | 897 Initialize(); |
| 690 | 898 |
| 691 BidirectionalStreamRequestInfo request; | 899 BidirectionalStreamRequestInfo request; |
| 692 request.method = "POST"; | 900 request.method = "POST"; |
| 693 request.url = GURL("http://www.google.com/"); | 901 request.url = GURL("http://www.google.com/"); |
| 694 request.end_stream_on_headers = false; | 902 request.end_stream_on_headers = false; |
| 695 request.priority = DEFAULT_PRIORITY; | 903 request.priority = DEFAULT_PRIORITY; |
| 696 | 904 |
| 697 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); | 905 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); |
| 698 std::unique_ptr<TestDelegateBase> delegate( | 906 std::unique_ptr<TestDelegateBase> delegate( |
| 699 new TestDelegateBase(read_buffer.get(), kReadBufferSize)); | 907 new TestDelegateBase(read_buffer.get(), kReadBufferSize)); |
| 700 delegate->DisableAutoFlush(); | 908 delegate->DoNotSendRequestHeadersAutomatically(); |
| 701 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr()); | 909 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr()); |
| 702 delegate->WaitUntilNextCallback(); // OnStreamReady | 910 delegate->WaitUntilNextCallback(); // OnStreamReady |
| 703 | 911 |
| 704 // Send a Data packet. | 912 // Send a Data packet. |
| 705 scoped_refptr<StringIOBuffer> buf1(new StringIOBuffer(kBody1)); | 913 scoped_refptr<StringIOBuffer> buf1(new StringIOBuffer(kBody1)); |
| 706 scoped_refptr<StringIOBuffer> buf2(new StringIOBuffer(kBody2)); | 914 scoped_refptr<StringIOBuffer> buf2(new StringIOBuffer(kBody2)); |
| 707 | 915 |
| 708 std::vector<int> lengths = {buf1->size(), buf2->size()}; | 916 std::vector<int> lengths = {buf1->size(), buf2->size()}; |
| 709 delegate->SendvData({buf1, buf2}, lengths, !kFin); | 917 delegate->SendvData({buf1, buf2}, lengths, !kFin); |
| 710 delegate->WaitUntilNextCallback(); // OnDataSent | 918 delegate->WaitUntilNextCallback(); // OnDataSent |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 | 1541 |
| 1334 base::MessageLoop::current()->RunUntilIdle(); | 1542 base::MessageLoop::current()->RunUntilIdle(); |
| 1335 | 1543 |
| 1336 EXPECT_EQ(1, delegate->on_data_read_count()); | 1544 EXPECT_EQ(1, delegate->on_data_read_count()); |
| 1337 EXPECT_EQ(0, delegate->on_data_sent_count()); | 1545 EXPECT_EQ(0, delegate->on_data_sent_count()); |
| 1338 } | 1546 } |
| 1339 | 1547 |
| 1340 } // namespace test | 1548 } // namespace test |
| 1341 | 1549 |
| 1342 } // namespace net | 1550 } // namespace net |
| OLD | NEW |