| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/quic_http_stream.h" | 5 #include "net/quic/quic_http_stream.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "net/base/test_completion_callback.h" | 10 #include "net/base/test_completion_callback.h" |
| 11 #include "net/base/upload_bytes_element_reader.h" | 11 #include "net/base/upload_bytes_element_reader.h" |
| 12 #include "net/base/upload_data_stream.h" | 12 #include "net/base/upload_data_stream.h" |
| 13 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
| 14 #include "net/quic/congestion_control/receive_algorithm_interface.h" | 14 #include "net/quic/congestion_control/receive_algorithm_interface.h" |
| 15 #include "net/quic/congestion_control/send_algorithm_interface.h" | 15 #include "net/quic/congestion_control/send_algorithm_interface.h" |
| 16 #include "net/quic/crypto/crypto_protocol.h" | 16 #include "net/quic/crypto/crypto_protocol.h" |
| 17 #include "net/quic/crypto/quic_decrypter.h" | 17 #include "net/quic/crypto/quic_decrypter.h" |
| 18 #include "net/quic/crypto/quic_encrypter.h" | 18 #include "net/quic/crypto/quic_encrypter.h" |
| 19 #include "net/quic/quic_client_session.h" | 19 #include "net/quic/quic_client_session.h" |
| 20 #include "net/quic/quic_connection.h" | 20 #include "net/quic/quic_connection.h" |
| 21 #include "net/quic/quic_connection_helper.h" | 21 #include "net/quic/quic_connection_helper.h" |
| 22 #include "net/quic/quic_default_packet_writer.h" | 22 #include "net/quic/quic_default_packet_writer.h" |
| 23 #include "net/quic/quic_http_utils.h" | 23 #include "net/quic/quic_http_utils.h" |
| 24 #include "net/quic/quic_reliable_client_stream.h" | 24 #include "net/quic/quic_reliable_client_stream.h" |
| 25 #include "net/quic/spdy_utils.h" | 25 #include "net/quic/spdy_utils.h" |
| 26 #include "net/quic/test_tools/mock_clock.h" | 26 #include "net/quic/test_tools/mock_clock.h" |
| 27 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" | 27 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" |
| 28 #include "net/quic/test_tools/mock_random.h" | 28 #include "net/quic/test_tools/mock_random.h" |
| 29 #include "net/quic/test_tools/quic_connection_peer.h" | 29 #include "net/quic/test_tools/quic_connection_peer.h" |
| 30 #include "net/quic/test_tools/quic_test_packet_maker.h" |
| 30 #include "net/quic/test_tools/quic_test_utils.h" | 31 #include "net/quic/test_tools/quic_test_utils.h" |
| 31 #include "net/quic/test_tools/test_task_runner.h" | 32 #include "net/quic/test_tools/test_task_runner.h" |
| 32 #include "net/socket/socket_test_util.h" | 33 #include "net/socket/socket_test_util.h" |
| 33 #include "net/spdy/spdy_frame_builder.h" | 34 #include "net/spdy/spdy_frame_builder.h" |
| 34 #include "net/spdy/spdy_framer.h" | 35 #include "net/spdy/spdy_framer.h" |
| 35 #include "net/spdy/spdy_http_utils.h" | 36 #include "net/spdy/spdy_http_utils.h" |
| 36 #include "net/spdy/spdy_protocol.h" | 37 #include "net/spdy/spdy_protocol.h" |
| 37 #include "net/spdy/write_blocked_list.h" | 38 #include "net/spdy/write_blocked_list.h" |
| 38 #include "testing/gmock/include/gmock/gmock.h" | 39 #include "testing/gmock/include/gmock/gmock.h" |
| 39 #include "testing/gtest/include/gtest/gtest.h" | 40 #include "testing/gtest/include/gtest/gtest.h" |
| 40 | 41 |
| 41 using testing::_; | 42 using testing::_; |
| 42 using testing::AnyNumber; | 43 using testing::AnyNumber; |
| 43 using testing::Return; | 44 using testing::Return; |
| 44 | 45 |
| 45 namespace net { | 46 namespace net { |
| 46 namespace test { | 47 namespace test { |
| 47 namespace { | 48 namespace { |
| 48 | 49 |
| 49 const char kUploadData[] = "hello world!"; | 50 const char kUploadData[] = "hello world!"; |
| 50 | 51 |
| 51 class TestQuicConnection : public QuicConnection { | 52 class TestQuicConnection : public QuicConnection { |
| 52 public: | 53 public: |
| 53 TestQuicConnection(QuicGuid guid, | 54 TestQuicConnection(const QuicVersionVector& versions, |
| 55 QuicGuid guid, |
| 54 IPEndPoint address, | 56 IPEndPoint address, |
| 55 QuicConnectionHelper* helper, | 57 QuicConnectionHelper* helper, |
| 56 QuicPacketWriter* writer) | 58 QuicPacketWriter* writer) |
| 57 : QuicConnection(guid, address, helper, writer, false, | 59 : QuicConnection(guid, address, helper, writer, false, versions) { |
| 58 QuicSupportedVersions()) { | |
| 59 } | 60 } |
| 60 | 61 |
| 61 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { | 62 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { |
| 62 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); | 63 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); |
| 63 } | 64 } |
| 64 | 65 |
| 65 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { | 66 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { |
| 66 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); | 67 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); |
| 67 } | 68 } |
| 68 }; | 69 }; |
| 69 | 70 |
| 70 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { | 71 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { |
| 71 public: | 72 public: |
| 72 explicit TestReceiveAlgorithm(QuicCongestionFeedbackFrame* feedback) | 73 virtual bool GenerateCongestionFeedback( |
| 73 : feedback_(feedback) { | 74 QuicCongestionFeedbackFrame* /*congestion_feedback*/) { |
| 74 } | 75 return false; |
| 75 | |
| 76 bool GenerateCongestionFeedback( | |
| 77 QuicCongestionFeedbackFrame* congestion_feedback) { | |
| 78 if (feedback_ == NULL) { | |
| 79 return false; | |
| 80 } | |
| 81 *congestion_feedback = *feedback_; | |
| 82 return true; | |
| 83 } | 76 } |
| 84 | 77 |
| 85 MOCK_METHOD4(RecordIncomingPacket, | 78 MOCK_METHOD4(RecordIncomingPacket, |
| 86 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool)); | 79 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool)); |
| 87 | |
| 88 private: | |
| 89 MockClock clock_; | |
| 90 QuicCongestionFeedbackFrame* feedback_; | |
| 91 | |
| 92 DISALLOW_COPY_AND_ASSIGN(TestReceiveAlgorithm); | |
| 93 }; | 80 }; |
| 94 | 81 |
| 95 // Subclass of QuicHttpStream that closes itself when the first piece of data | 82 // Subclass of QuicHttpStream that closes itself when the first piece of data |
| 96 // is received. | 83 // is received. |
| 97 class AutoClosingStream : public QuicHttpStream { | 84 class AutoClosingStream : public QuicHttpStream { |
| 98 public: | 85 public: |
| 99 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) | 86 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) |
| 100 : QuicHttpStream(session) { | 87 : QuicHttpStream(session) { |
| 101 } | 88 } |
| 102 | 89 |
| 103 virtual int OnDataReceived(const char* data, int length) OVERRIDE { | 90 virtual int OnDataReceived(const char* data, int length) OVERRIDE { |
| 104 Close(false); | 91 Close(false); |
| 105 return OK; | 92 return OK; |
| 106 } | 93 } |
| 107 }; | 94 }; |
| 108 | 95 |
| 109 } // namespace | 96 } // namespace |
| 110 | 97 |
| 111 class QuicHttpStreamPeer { | 98 class QuicHttpStreamPeer { |
| 112 public: | 99 public: |
| 113 static QuicReliableClientStream* GetQuicReliableClientStream( | 100 static QuicReliableClientStream* GetQuicReliableClientStream( |
| 114 QuicHttpStream* stream) { | 101 QuicHttpStream* stream) { |
| 115 return stream->stream_; | 102 return stream->stream_; |
| 116 } | 103 } |
| 117 }; | 104 }; |
| 118 | 105 |
| 119 class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { | 106 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { |
| 120 protected: | 107 protected: |
| 121 const static bool kFin = true; | 108 static const bool kFin = true; |
| 109 static const bool kIncludeVersion = true; |
| 110 static const bool kIncludeCongestionFeedback = true; |
| 111 |
| 122 // Holds a packet to be written to the wire, and the IO mode that should | 112 // Holds a packet to be written to the wire, and the IO mode that should |
| 123 // be used by the mock socket when performing the write. | 113 // be used by the mock socket when performing the write. |
| 124 struct PacketToWrite { | 114 struct PacketToWrite { |
| 125 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) | 115 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) |
| 126 : mode(mode), | 116 : mode(mode), |
| 127 packet(packet) { | 117 packet(packet) { |
| 128 } | 118 } |
| 129 IoMode mode; | 119 IoMode mode; |
| 130 QuicEncryptedPacket* packet; | 120 QuicEncryptedPacket* packet; |
| 131 }; | 121 }; |
| 132 | 122 |
| 133 QuicHttpStreamTest() | 123 QuicHttpStreamTest() |
| 134 : net_log_(BoundNetLog()), | 124 : net_log_(BoundNetLog()), |
| 135 use_closing_stream_(false), | 125 use_closing_stream_(false), |
| 136 read_buffer_(new IOBufferWithSize(4096)), | 126 read_buffer_(new IOBufferWithSize(4096)), |
| 137 guid_(2), | 127 guid_(2), |
| 138 framer_(QuicSupportedVersions(), QuicTime::Zero(), false), | 128 stream_id_(GetParam() > QUIC_VERSION_12 ? 5 : 3), |
| 139 random_generator_(0), | 129 maker_(GetParam(), guid_), |
| 140 creator_(guid_, &framer_, &random_generator_, false) { | 130 random_generator_(0) { |
| 141 IPAddressNumber ip; | 131 IPAddressNumber ip; |
| 142 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); | 132 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); |
| 143 peer_addr_ = IPEndPoint(ip, 443); | 133 peer_addr_ = IPEndPoint(ip, 443); |
| 144 self_addr_ = IPEndPoint(ip, 8435); | 134 self_addr_ = IPEndPoint(ip, 8435); |
| 145 } | 135 } |
| 146 | 136 |
| 147 ~QuicHttpStreamTest() { | 137 ~QuicHttpStreamTest() { |
| 148 session_->CloseSessionOnError(ERR_ABORTED); | 138 session_->CloseSessionOnError(ERR_ABORTED); |
| 149 for (size_t i = 0; i < writes_.size(); i++) { | 139 for (size_t i = 0; i < writes_.size(); i++) { |
| 150 delete writes_[i].packet; | 140 delete writes_[i].packet; |
| 151 } | 141 } |
| 152 } | 142 } |
| 153 | 143 |
| 154 // Adds a packet to the list of expected writes. | 144 // Adds a packet to the list of expected writes. |
| 155 void AddWrite(IoMode mode, QuicEncryptedPacket* packet) { | 145 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) { |
| 156 writes_.push_back(PacketToWrite(mode, packet)); | 146 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release())); |
| 157 } | 147 } |
| 158 | 148 |
| 159 // Returns the packet to be written at position |pos|. | 149 // Returns the packet to be written at position |pos|. |
| 160 QuicEncryptedPacket* GetWrite(size_t pos) { | 150 QuicEncryptedPacket* GetWrite(size_t pos) { |
| 161 return writes_[pos].packet; | 151 return writes_[pos].packet; |
| 162 } | 152 } |
| 163 | 153 |
| 164 bool AtEof() { | 154 bool AtEof() { |
| 165 return socket_data_->at_read_eof() && socket_data_->at_write_eof(); | 155 return socket_data_->at_read_eof() && socket_data_->at_write_eof(); |
| 166 } | 156 } |
| 167 | 157 |
| 168 void ProcessPacket(const QuicEncryptedPacket& packet) { | 158 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) { |
| 169 connection_->ProcessUdpPacket(self_addr_, peer_addr_, packet); | 159 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet); |
| 170 } | 160 } |
| 171 | 161 |
| 172 // Configures the test fixture to use the list of expected writes. | 162 // Configures the test fixture to use the list of expected writes. |
| 173 void Initialize() { | 163 void Initialize() { |
| 174 mock_writes_.reset(new MockWrite[writes_.size()]); | 164 mock_writes_.reset(new MockWrite[writes_.size()]); |
| 175 for (size_t i = 0; i < writes_.size(); i++) { | 165 for (size_t i = 0; i < writes_.size(); i++) { |
| 176 mock_writes_[i] = MockWrite(writes_[i].mode, | 166 mock_writes_[i] = MockWrite(writes_[i].mode, |
| 177 writes_[i].packet->data(), | 167 writes_[i].packet->data(), |
| 178 writes_[i].packet->length()); | 168 writes_[i].packet->length()); |
| 179 }; | 169 }; |
| 180 | 170 |
| 181 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), | 171 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), |
| 182 writes_.size())); | 172 writes_.size())); |
| 183 | 173 |
| 184 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), | 174 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), |
| 185 net_log_.net_log()); | 175 net_log_.net_log()); |
| 186 socket->Connect(peer_addr_); | 176 socket->Connect(peer_addr_); |
| 187 runner_ = new TestTaskRunner(&clock_); | 177 runner_ = new TestTaskRunner(&clock_); |
| 188 send_algorithm_ = new MockSendAlgorithm(); | 178 send_algorithm_ = new MockSendAlgorithm(); |
| 189 receive_algorithm_ = new TestReceiveAlgorithm(NULL); | 179 receive_algorithm_ = new TestReceiveAlgorithm(); |
| 190 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). | 180 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). |
| 191 Times(AnyNumber()); | 181 Times(AnyNumber()); |
| 192 EXPECT_CALL(*send_algorithm_, | 182 EXPECT_CALL(*send_algorithm_, |
| 193 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); | 183 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); |
| 194 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( | 184 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( |
| 195 Return(QuicTime::Delta::Zero())); | 185 Return(QuicTime::Delta::Zero())); |
| 196 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 186 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
| 197 WillRepeatedly(Return(QuicTime::Delta::Zero())); | 187 WillRepeatedly(Return(QuicTime::Delta::Zero())); |
| 198 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly( | 188 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly( |
| 199 Return(QuicTime::Delta::Zero())); | 189 Return(QuicTime::Delta::Zero())); |
| 200 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( | 190 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( |
| 201 Return(QuicBandwidth::Zero())); | 191 Return(QuicBandwidth::Zero())); |
| 202 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber()); | 192 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber()); |
| 203 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, | 193 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, |
| 204 &random_generator_)); | 194 &random_generator_)); |
| 205 writer_.reset(new QuicDefaultPacketWriter(socket)); | 195 writer_.reset(new QuicDefaultPacketWriter(socket)); |
| 206 connection_ = new TestQuicConnection(guid_, peer_addr_, helper_.get(), | 196 connection_ = new TestQuicConnection(SupportedVersions(GetParam()), guid_, |
| 197 peer_addr_, helper_.get(), |
| 207 writer_.get()); | 198 writer_.get()); |
| 208 connection_->set_visitor(&visitor_); | 199 connection_->set_visitor(&visitor_); |
| 209 connection_->SetSendAlgorithm(send_algorithm_); | 200 connection_->SetSendAlgorithm(send_algorithm_); |
| 210 connection_->SetReceiveAlgorithm(receive_algorithm_); | 201 connection_->SetReceiveAlgorithm(receive_algorithm_); |
| 211 crypto_config_.SetDefaults(); | 202 crypto_config_.SetDefaults(); |
| 212 session_.reset( | 203 session_.reset( |
| 213 new QuicClientSession(connection_, | 204 new QuicClientSession(connection_, |
| 214 scoped_ptr<DatagramClientSocket>(socket), | 205 scoped_ptr<DatagramClientSocket>(socket), |
| 215 writer_.Pass(), NULL, | 206 writer_.Pass(), NULL, |
| 216 &crypto_client_stream_factory_, | 207 &crypto_client_stream_factory_, |
| 217 "www.google.com", DefaultQuicConfig(), | 208 "www.google.com", DefaultQuicConfig(), |
| 218 &crypto_config_, NULL)); | 209 &crypto_config_, NULL)); |
| 219 session_->GetCryptoStream()->CryptoConnect(); | 210 session_->GetCryptoStream()->CryptoConnect(); |
| 220 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); | 211 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); |
| 221 stream_.reset(use_closing_stream_ ? | 212 stream_.reset(use_closing_stream_ ? |
| 222 new AutoClosingStream(session_->GetWeakPtr()) : | 213 new AutoClosingStream(session_->GetWeakPtr()) : |
| 223 new QuicHttpStream(session_->GetWeakPtr())); | 214 new QuicHttpStream(session_->GetWeakPtr())); |
| 224 } | 215 } |
| 225 | 216 |
| 226 void SetRequestString(const std::string& method, | 217 void SetRequest(const std::string& method, |
| 227 const std::string& path, | 218 const std::string& path, |
| 228 RequestPriority priority) { | 219 RequestPriority priority) { |
| 229 SpdyHeaderBlock headers; | 220 request_headers_ = maker_.GetRequestHeaders(method, "http", path); |
| 230 headers[":method"] = method; | 221 request_data_ = GetParam() > QUIC_VERSION_12 ? "" : |
| 231 headers[":host"] = "www.google.com"; | 222 SerializeHeaderBlock(request_headers_, true, priority); |
| 232 headers[":path"] = path; | |
| 233 headers[":scheme"] = "http"; | |
| 234 headers[":version"] = "HTTP/1.1"; | |
| 235 request_data_ = SerializeHeaderBlock(headers, true, priority); | |
| 236 } | 223 } |
| 237 | 224 |
| 238 void SetResponseString(const std::string& status, const std::string& body) { | 225 void SetResponse(const std::string& status, const std::string& body) { |
| 239 SpdyHeaderBlock headers; | 226 response_headers_ = maker_.GetResponseHeaders(status); |
| 240 headers[":status"] = status; | 227 if (GetParam() > QUIC_VERSION_12) { |
| 241 headers[":version"] = "HTTP/1.1"; | 228 response_data_ = body; |
| 242 headers["content-type"] = "text/plain"; | 229 } else { |
| 243 response_data_ = SerializeHeaderBlock(headers, false, DEFAULT_PRIORITY) + | 230 response_data_ = |
| 244 body; | 231 SerializeHeaderBlock(response_headers_, false, DEFAULT_PRIORITY) + |
| 232 body; |
| 233 } |
| 245 } | 234 } |
| 246 | 235 |
| 247 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers, | 236 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket( |
| 248 bool write_priority, | |
| 249 RequestPriority priority) { | |
| 250 QuicSpdyCompressor compressor; | |
| 251 if (write_priority) { | |
| 252 return compressor.CompressHeadersWithPriority( | |
| 253 ConvertRequestPriorityToQuicPriority(priority), headers); | |
| 254 } | |
| 255 return compressor.CompressHeaders(headers); | |
| 256 } | |
| 257 | |
| 258 // Returns a newly created packet to send kData on stream 3. | |
| 259 QuicEncryptedPacket* ConstructDataPacket( | |
| 260 QuicPacketSequenceNumber sequence_number, | 237 QuicPacketSequenceNumber sequence_number, |
| 261 bool should_include_version, | 238 bool should_include_version, |
| 262 bool fin, | 239 bool fin, |
| 263 QuicStreamOffset offset, | 240 QuicStreamOffset offset, |
| 264 base::StringPiece data) { | 241 base::StringPiece data) { |
| 265 InitializeHeader(sequence_number, should_include_version); | 242 return maker_.MakeDataPacket( |
| 266 QuicStreamFrame frame(3, fin, offset, MakeIOVector(data)); | 243 sequence_number, stream_id_, should_include_version, fin, offset, data); |
| 267 return ConstructPacket(header_, QuicFrame(&frame)); | |
| 268 } | 244 } |
| 269 | 245 |
| 270 // Returns a newly created packet to RST_STREAM stream 3. | 246 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket( |
| 271 QuicEncryptedPacket* ConstructRstStreamPacket( | 247 QuicPacketSequenceNumber sequence_number, |
| 272 QuicPacketSequenceNumber sequence_number) { | 248 bool fin) { |
| 273 InitializeHeader(sequence_number, false); | 249 return maker_.MakeRequestHeadersPacket( |
| 274 QuicRstStreamFrame frame(3, QUIC_STREAM_CANCELLED); | 250 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_); |
| 275 return ConstructPacket(header_, QuicFrame(&frame)); | |
| 276 } | 251 } |
| 277 | 252 |
| 278 // Returns a newly created packet to send ack data. | 253 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket( |
| 279 QuicEncryptedPacket* ConstructAckPacket( | 254 QuicPacketSequenceNumber sequence_number, |
| 255 bool fin) { |
| 256 return maker_.MakeResponseHeadersPacket( |
| 257 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_); |
| 258 } |
| 259 |
| 260 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket( |
| 261 QuicPacketSequenceNumber sequence_number) { |
| 262 return maker_.MakeRstPacket( |
| 263 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED); |
| 264 } |
| 265 |
| 266 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( |
| 280 QuicPacketSequenceNumber sequence_number, | 267 QuicPacketSequenceNumber sequence_number, |
| 281 QuicPacketSequenceNumber largest_received, | 268 QuicPacketSequenceNumber largest_received, |
| 282 QuicPacketSequenceNumber least_unacked) { | 269 QuicPacketSequenceNumber least_unacked) { |
| 283 InitializeHeader(sequence_number, false); | 270 return maker_.MakeAckPacket(sequence_number, largest_received, |
| 284 | 271 least_unacked, !kIncludeCongestionFeedback); |
| 285 QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked); | |
| 286 ack.sent_info.entropy_hash = 0; | |
| 287 ack.received_info.entropy_hash = 0; | |
| 288 | |
| 289 return ConstructPacket(header_, QuicFrame(&ack)); | |
| 290 } | |
| 291 | |
| 292 // Returns a newly created packet to send ack data. | |
| 293 QuicEncryptedPacket* ConstructRstPacket( | |
| 294 QuicPacketSequenceNumber sequence_number, | |
| 295 QuicStreamId stream_id) { | |
| 296 InitializeHeader(sequence_number, false); | |
| 297 | |
| 298 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR); | |
| 299 return ConstructPacket(header_, QuicFrame(&rst)); | |
| 300 } | 272 } |
| 301 | 273 |
| 302 BoundNetLog net_log_; | 274 BoundNetLog net_log_; |
| 303 bool use_closing_stream_; | 275 bool use_closing_stream_; |
| 304 MockSendAlgorithm* send_algorithm_; | 276 MockSendAlgorithm* send_algorithm_; |
| 305 TestReceiveAlgorithm* receive_algorithm_; | 277 TestReceiveAlgorithm* receive_algorithm_; |
| 306 scoped_refptr<TestTaskRunner> runner_; | 278 scoped_refptr<TestTaskRunner> runner_; |
| 307 scoped_ptr<MockWrite[]> mock_writes_; | 279 scoped_ptr<MockWrite[]> mock_writes_; |
| 308 MockClock clock_; | 280 MockClock clock_; |
| 309 TestQuicConnection* connection_; | 281 TestQuicConnection* connection_; |
| 310 scoped_ptr<QuicConnectionHelper> helper_; | 282 scoped_ptr<QuicConnectionHelper> helper_; |
| 311 testing::StrictMock<MockConnectionVisitor> visitor_; | 283 testing::StrictMock<MockConnectionVisitor> visitor_; |
| 312 scoped_ptr<QuicHttpStream> stream_; | 284 scoped_ptr<QuicHttpStream> stream_; |
| 313 scoped_ptr<QuicDefaultPacketWriter> writer_; | 285 scoped_ptr<QuicDefaultPacketWriter> writer_; |
| 314 scoped_ptr<QuicClientSession> session_; | 286 scoped_ptr<QuicClientSession> session_; |
| 315 QuicCryptoClientConfig crypto_config_; | 287 QuicCryptoClientConfig crypto_config_; |
| 316 TestCompletionCallback callback_; | 288 TestCompletionCallback callback_; |
| 317 HttpRequestInfo request_; | 289 HttpRequestInfo request_; |
| 318 HttpRequestHeaders headers_; | 290 HttpRequestHeaders headers_; |
| 319 HttpResponseInfo response_; | 291 HttpResponseInfo response_; |
| 320 scoped_refptr<IOBufferWithSize> read_buffer_; | 292 scoped_refptr<IOBufferWithSize> read_buffer_; |
| 293 SpdyHeaderBlock request_headers_; |
| 294 SpdyHeaderBlock response_headers_; |
| 321 std::string request_data_; | 295 std::string request_data_; |
| 322 std::string response_data_; | 296 std::string response_data_; |
| 323 | 297 |
| 324 private: | 298 private: |
| 325 void InitializeHeader(QuicPacketSequenceNumber sequence_number, | 299 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers, |
| 326 bool should_include_version) { | 300 bool write_priority, |
| 327 header_.public_header.guid = guid_; | 301 RequestPriority priority) { |
| 328 header_.public_header.reset_flag = false; | 302 QuicSpdyCompressor compressor; |
| 329 header_.public_header.version_flag = should_include_version; | 303 if (write_priority) { |
| 330 header_.public_header.sequence_number_length = PACKET_1BYTE_SEQUENCE_NUMBER; | 304 return compressor.CompressHeadersWithPriority( |
| 331 header_.packet_sequence_number = sequence_number; | 305 ConvertRequestPriorityToQuicPriority(priority), headers); |
| 332 header_.fec_group = 0; | 306 } |
| 333 header_.entropy_flag = false; | 307 return compressor.CompressHeaders(headers); |
| 334 header_.fec_flag = false; | |
| 335 } | |
| 336 | |
| 337 QuicEncryptedPacket* ConstructPacket(const QuicPacketHeader& header, | |
| 338 const QuicFrame& frame) { | |
| 339 QuicFrames frames; | |
| 340 frames.push_back(frame); | |
| 341 scoped_ptr<QuicPacket> packet( | |
| 342 framer_.BuildUnsizedDataPacket(header_, frames).packet); | |
| 343 return framer_.EncryptPacket( | |
| 344 ENCRYPTION_NONE, header.packet_sequence_number, *packet); | |
| 345 } | 308 } |
| 346 | 309 |
| 347 const QuicGuid guid_; | 310 const QuicGuid guid_; |
| 348 QuicFramer framer_; | 311 const QuicStreamId stream_id_; |
| 312 QuicTestPacketMaker maker_; |
| 349 IPEndPoint self_addr_; | 313 IPEndPoint self_addr_; |
| 350 IPEndPoint peer_addr_; | 314 IPEndPoint peer_addr_; |
| 351 MockRandom random_generator_; | 315 MockRandom random_generator_; |
| 352 MockCryptoClientStreamFactory crypto_client_stream_factory_; | 316 MockCryptoClientStreamFactory crypto_client_stream_factory_; |
| 353 QuicPacketCreator creator_; | |
| 354 QuicPacketHeader header_; | |
| 355 scoped_ptr<StaticSocketDataProvider> socket_data_; | 317 scoped_ptr<StaticSocketDataProvider> socket_data_; |
| 356 std::vector<PacketToWrite> writes_; | 318 std::vector<PacketToWrite> writes_; |
| 357 }; | 319 }; |
| 358 | 320 |
| 359 TEST_F(QuicHttpStreamTest, RenewStreamForAuth) { | 321 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest, |
| 322 ::testing::ValuesIn(QuicSupportedVersions())); |
| 323 |
| 324 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) { |
| 360 Initialize(); | 325 Initialize(); |
| 361 EXPECT_EQ(NULL, stream_->RenewStreamForAuth()); | 326 EXPECT_EQ(NULL, stream_->RenewStreamForAuth()); |
| 362 } | 327 } |
| 363 | 328 |
| 364 TEST_F(QuicHttpStreamTest, CanFindEndOfResponse) { | 329 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) { |
| 365 Initialize(); | 330 Initialize(); |
| 366 EXPECT_TRUE(stream_->CanFindEndOfResponse()); | 331 EXPECT_TRUE(stream_->CanFindEndOfResponse()); |
| 367 } | 332 } |
| 368 | 333 |
| 369 TEST_F(QuicHttpStreamTest, IsConnectionReusable) { | 334 TEST_P(QuicHttpStreamTest, IsConnectionReusable) { |
| 370 Initialize(); | 335 Initialize(); |
| 371 EXPECT_FALSE(stream_->IsConnectionReusable()); | 336 EXPECT_FALSE(stream_->IsConnectionReusable()); |
| 372 } | 337 } |
| 373 | 338 |
| 374 TEST_F(QuicHttpStreamTest, GetRequest) { | 339 TEST_P(QuicHttpStreamTest, GetRequest) { |
| 375 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 340 SetRequest("GET", "/", DEFAULT_PRIORITY); |
| 376 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, | 341 if (GetParam() > QUIC_VERSION_12) { |
| 377 request_data_)); | 342 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 343 } else { |
| 344 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 345 } |
| 378 Initialize(); | 346 Initialize(); |
| 379 | 347 |
| 380 request_.method = "GET"; | 348 request_.method = "GET"; |
| 381 request_.url = GURL("http://www.google.com/"); | 349 request_.url = GURL("http://www.google.com/"); |
| 382 | 350 |
| 383 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 351 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 384 net_log_, callback_.callback())); | 352 net_log_, callback_.callback())); |
| 385 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 353 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 386 callback_.callback())); | 354 callback_.callback())); |
| 387 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 355 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 388 | 356 |
| 389 // Ack the request. | 357 // Ack the request. |
| 390 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 358 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 391 ProcessPacket(*ack); | |
| 392 | 359 |
| 393 EXPECT_EQ(ERR_IO_PENDING, | 360 EXPECT_EQ(ERR_IO_PENDING, |
| 394 stream_->ReadResponseHeaders(callback_.callback())); | 361 stream_->ReadResponseHeaders(callback_.callback())); |
| 395 | 362 |
| 396 // Send the response without a body. | 363 SetResponse("404 Not Found", std::string()); |
| 397 SetResponseString("404 Not Found", std::string()); | 364 if (GetParam() > QUIC_VERSION_12) { |
| 398 scoped_ptr<QuicEncryptedPacket> resp( | 365 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
| 399 ConstructDataPacket(2, false, kFin, 0, response_data_)); | 366 } else { |
| 400 ProcessPacket(*resp); | 367 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 368 } |
| 401 | 369 |
| 402 // Now that the headers have been processed, the callback will return. | 370 // Now that the headers have been processed, the callback will return. |
| 403 EXPECT_EQ(OK, callback_.WaitForResult()); | 371 EXPECT_EQ(OK, callback_.WaitForResult()); |
| 404 ASSERT_TRUE(response_.headers.get()); | 372 ASSERT_TRUE(response_.headers.get()); |
| 405 EXPECT_EQ(404, response_.headers->response_code()); | 373 EXPECT_EQ(404, response_.headers->response_code()); |
| 406 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 374 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
| 407 | 375 |
| 408 // There is no body, so this should return immediately. | 376 // There is no body, so this should return immediately. |
| 409 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), | 377 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
| 410 read_buffer_->size(), | 378 read_buffer_->size(), |
| 411 callback_.callback())); | 379 callback_.callback())); |
| 412 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 380 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 413 EXPECT_TRUE(AtEof()); | 381 EXPECT_TRUE(AtEof()); |
| 414 } | 382 } |
| 415 | 383 |
| 416 // Regression test for http://crbug.com/288128 | 384 // Regression test for http://crbug.com/288128 |
| 417 TEST_F(QuicHttpStreamTest, GetRequestLargeResponse) { | 385 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) { |
| 418 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 386 SetRequest("GET", "/", DEFAULT_PRIORITY); |
| 419 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, | 387 if (GetParam() > QUIC_VERSION_12) { |
| 420 request_data_)); | 388 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 389 } else { |
| 390 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 391 } |
| 421 Initialize(); | 392 Initialize(); |
| 422 | 393 |
| 423 request_.method = "GET"; | 394 request_.method = "GET"; |
| 424 request_.url = GURL("http://www.google.com/"); | 395 request_.url = GURL("http://www.google.com/"); |
| 425 | 396 |
| 426 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 397 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 427 net_log_, callback_.callback())); | 398 net_log_, callback_.callback())); |
| 428 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 399 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 429 callback_.callback())); | 400 callback_.callback())); |
| 430 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 401 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 431 | 402 |
| 432 // Ack the request. | 403 // Ack the request. |
| 433 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 404 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 434 ProcessPacket(*ack); | |
| 435 | 405 |
| 436 EXPECT_EQ(ERR_IO_PENDING, | 406 EXPECT_EQ(ERR_IO_PENDING, |
| 437 stream_->ReadResponseHeaders(callback_.callback())); | 407 stream_->ReadResponseHeaders(callback_.callback())); |
| 438 | 408 |
| 439 SpdyHeaderBlock headers; | 409 SpdyHeaderBlock headers; |
| 440 headers[":status"] = "200 OK"; | 410 headers[":status"] = "200 OK"; |
| 441 headers[":version"] = "HTTP/1.1"; | 411 headers[":version"] = "HTTP/1.1"; |
| 442 headers["content-type"] = "text/plain"; | 412 headers["content-type"] = "text/plain"; |
| 443 headers["big6"] = std::string(10000, 'x'); // Lots of x's. | 413 headers["big6"] = std::string(10000, 'x'); // Lots of x's. |
| 444 | 414 |
| 445 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); | 415 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); |
| 446 EXPECT_LT(4096u, response.length()); | 416 EXPECT_LT(4096u, response.length()); |
| 447 stream_->OnDataReceived(response.data(), response.length()); | 417 stream_->OnDataReceived(response.data(), response.length()); |
| 448 stream_->OnClose(QUIC_NO_ERROR); | 418 stream_->OnClose(QUIC_NO_ERROR); |
| 449 | 419 |
| 450 // Now that the headers have been processed, the callback will return. | 420 // Now that the headers have been processed, the callback will return. |
| 451 EXPECT_EQ(OK, callback_.WaitForResult()); | 421 EXPECT_EQ(OK, callback_.WaitForResult()); |
| 452 ASSERT_TRUE(response_.headers.get()); | 422 ASSERT_TRUE(response_.headers.get()); |
| 453 EXPECT_EQ(200, response_.headers->response_code()); | 423 EXPECT_EQ(200, response_.headers->response_code()); |
| 454 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 424 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
| 455 | 425 |
| 456 // There is no body, so this should return immediately. | 426 // There is no body, so this should return immediately. |
| 457 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), | 427 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
| 458 read_buffer_->size(), | 428 read_buffer_->size(), |
| 459 callback_.callback())); | 429 callback_.callback())); |
| 460 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 430 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 461 EXPECT_TRUE(AtEof()); | 431 EXPECT_TRUE(AtEof()); |
| 462 } | 432 } |
| 463 | 433 |
| 464 TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) { | 434 TEST_P(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) { |
| 465 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 435 SetRequest("GET", "/", DEFAULT_PRIORITY); |
| 466 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 436 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 467 Initialize(); | 437 Initialize(); |
| 468 | 438 |
| 439 if (GetParam() > QUIC_VERSION_12) { |
| 440 // we can't put the request and response into a single frame. |
| 441 return; |
| 442 } |
| 443 |
| 469 request_.method = "GET"; | 444 request_.method = "GET"; |
| 470 request_.url = GURL("http://www.google.com/"); | 445 request_.url = GURL("http://www.google.com/"); |
| 471 | 446 |
| 472 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 447 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 473 net_log_, callback_.callback())); | 448 net_log_, callback_.callback())); |
| 474 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 449 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 475 callback_.callback())); | 450 callback_.callback())); |
| 476 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 451 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 477 | 452 |
| 478 // Ack the request. | 453 // Ack the request. |
| 479 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 454 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 480 ProcessPacket(*ack); | |
| 481 | 455 |
| 482 EXPECT_EQ(ERR_IO_PENDING, | 456 EXPECT_EQ(ERR_IO_PENDING, |
| 483 stream_->ReadResponseHeaders(callback_.callback())); | 457 stream_->ReadResponseHeaders(callback_.callback())); |
| 484 | 458 |
| 485 // Send the response with a body. | 459 // Send the response with a body. |
| 486 SetResponseString("200 OK", "hello world!"); | 460 SetResponse("200 OK", "hello world!"); |
| 487 scoped_ptr<QuicEncryptedPacket> resp( | 461 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 488 ConstructDataPacket(2, false, kFin, 0, response_data_)); | |
| 489 ProcessPacket(*resp); | |
| 490 | 462 |
| 491 // Now that the headers have been processed, the callback will return. | 463 // Now that the headers have been processed, the callback will return. |
| 492 EXPECT_EQ(OK, callback_.WaitForResult()); | 464 EXPECT_EQ(OK, callback_.WaitForResult()); |
| 493 ASSERT_TRUE(response_.headers.get()); | 465 ASSERT_TRUE(response_.headers.get()); |
| 494 EXPECT_EQ(200, response_.headers->response_code()); | 466 EXPECT_EQ(200, response_.headers->response_code()); |
| 495 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 467 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
| 496 | 468 |
| 497 // There is no body, so this should return immediately. | 469 // There is no body, so this should return immediately. |
| 498 // Since the body has already arrived, this should return immediately. | 470 // Since the body has already arrived, this should return immediately. |
| 499 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(), | 471 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(), |
| 500 read_buffer_->size(), | 472 read_buffer_->size(), |
| 501 callback_.callback())); | 473 callback_.callback())); |
| 502 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 474 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 503 EXPECT_TRUE(AtEof()); | 475 EXPECT_TRUE(AtEof()); |
| 504 } | 476 } |
| 505 | 477 |
| 506 TEST_F(QuicHttpStreamTest, SendPostRequest) { | 478 TEST_P(QuicHttpStreamTest, SendPostRequest) { |
| 507 SetRequestString("POST", "/", DEFAULT_PRIORITY); | 479 SetRequest("POST", "/", DEFAULT_PRIORITY); |
| 508 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); | 480 if (GetParam() > QUIC_VERSION_12) { |
| 509 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin, | 481 AddWrite(ConstructRequestHeadersPacket(1, !kFin)); |
| 510 request_data_.length(), | 482 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData)); |
| 511 kUploadData)); | 483 } else { |
| 512 AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1)); | 484 AddWrite(ConstructDataPacket(1, kIncludeVersion, !kFin, 0, request_data_)); |
| 485 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, |
| 486 request_data_.length(), kUploadData)); |
| 487 } |
| 488 AddWrite(ConstructAckPacket(3, 3, 1)); |
| 513 | 489 |
| 514 Initialize(); | 490 Initialize(); |
| 515 | 491 |
| 516 ScopedVector<UploadElementReader> element_readers; | 492 ScopedVector<UploadElementReader> element_readers; |
| 517 element_readers.push_back( | 493 element_readers.push_back( |
| 518 new UploadBytesElementReader(kUploadData, strlen(kUploadData))); | 494 new UploadBytesElementReader(kUploadData, strlen(kUploadData))); |
| 519 UploadDataStream upload_data_stream(element_readers.Pass(), 0); | 495 UploadDataStream upload_data_stream(element_readers.Pass(), 0); |
| 520 request_.method = "POST"; | 496 request_.method = "POST"; |
| 521 request_.url = GURL("http://www.google.com/"); | 497 request_.url = GURL("http://www.google.com/"); |
| 522 request_.upload_data_stream = &upload_data_stream; | 498 request_.upload_data_stream = &upload_data_stream; |
| 523 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); | 499 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); |
| 524 | 500 |
| 525 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 501 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 526 net_log_, callback_.callback())); | 502 net_log_, callback_.callback())); |
| 527 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 503 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 528 callback_.callback())); | 504 callback_.callback())); |
| 529 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 505 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 530 | 506 |
| 531 // Ack both packets in the request. | 507 // Ack both packets in the request. |
| 532 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 508 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 533 ProcessPacket(*ack); | |
| 534 | 509 |
| 535 // Send the response headers (but not the body). | 510 // Send the response headers (but not the body). |
| 536 SetResponseString("200 OK", std::string()); | 511 SetResponse("200 OK", std::string()); |
| 537 scoped_ptr<QuicEncryptedPacket> resp( | 512 if (GetParam() > QUIC_VERSION_12) { |
| 538 ConstructDataPacket(2, false, !kFin, 0, response_data_)); | 513 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
| 539 ProcessPacket(*resp); | 514 } else { |
| 515 ProcessPacket(ConstructDataPacket(2, false, !kFin, 0, response_data_)); |
| 516 } |
| 540 | 517 |
| 541 // Since the headers have already arrived, this should return immediately. | 518 // Since the headers have already arrived, this should return immediately. |
| 542 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); | 519 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
| 543 ASSERT_TRUE(response_.headers.get()); | 520 ASSERT_TRUE(response_.headers.get()); |
| 544 EXPECT_EQ(200, response_.headers->response_code()); | 521 EXPECT_EQ(200, response_.headers->response_code()); |
| 545 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 522 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
| 546 | 523 |
| 547 // Send the response body. | 524 // Send the response body. |
| 548 const char kResponseBody[] = "Hello world!"; | 525 const char kResponseBody[] = "Hello world!"; |
| 549 scoped_ptr<QuicEncryptedPacket> resp_body( | 526 if (GetParam() > QUIC_VERSION_12) { |
| 550 ConstructDataPacket(3, false, kFin, response_data_.length(), | 527 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody)); |
| 551 kResponseBody)); | 528 } else { |
| 552 ProcessPacket(*resp_body); | 529 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
| 553 | 530 kResponseBody)); |
| 531 } |
| 554 // Since the body has already arrived, this should return immediately. | 532 // Since the body has already arrived, this should return immediately. |
| 555 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), | 533 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), |
| 556 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), | 534 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
| 557 callback_.callback())); | 535 callback_.callback())); |
| 558 | 536 |
| 559 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 537 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 560 EXPECT_TRUE(AtEof()); | 538 EXPECT_TRUE(AtEof()); |
| 561 } | 539 } |
| 562 | 540 |
| 563 TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) { | 541 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) { |
| 564 SetRequestString("POST", "/", DEFAULT_PRIORITY); | 542 SetRequest("POST", "/", DEFAULT_PRIORITY); |
| 565 size_t chunk_size = strlen(kUploadData); | 543 size_t chunk_size = strlen(kUploadData); |
| 566 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); | 544 if (GetParam() > QUIC_VERSION_12) { |
| 567 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin, | 545 AddWrite(ConstructRequestHeadersPacket(1, !kFin)); |
| 568 request_data_.length(), | 546 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); |
| 569 kUploadData)); | 547 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, |
| 570 AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin, | 548 kUploadData)); |
| 571 request_data_.length() + chunk_size, | 549 } else { |
| 572 kUploadData)); | 550 AddWrite(ConstructDataPacket(1, kIncludeVersion, !kFin, 0, request_data_)); |
| 573 AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1)); | 551 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, |
| 574 | 552 request_data_.length(), kUploadData)); |
| 553 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, |
| 554 request_data_.length() + chunk_size, |
| 555 kUploadData)); |
| 556 } |
| 557 AddWrite(ConstructAckPacket(4, 3, 1)); |
| 575 Initialize(); | 558 Initialize(); |
| 576 | 559 |
| 577 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); | 560 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); |
| 578 upload_data_stream.AppendChunk(kUploadData, chunk_size, false); | 561 upload_data_stream.AppendChunk(kUploadData, chunk_size, false); |
| 579 | 562 |
| 580 request_.method = "POST"; | 563 request_.method = "POST"; |
| 581 request_.url = GURL("http://www.google.com/"); | 564 request_.url = GURL("http://www.google.com/"); |
| 582 request_.upload_data_stream = &upload_data_stream; | 565 request_.upload_data_stream = &upload_data_stream; |
| 583 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); | 566 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); |
| 584 | 567 |
| 585 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 568 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 586 net_log_, callback_.callback())); | 569 net_log_, callback_.callback())); |
| 587 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, | 570 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
| 588 callback_.callback())); | 571 callback_.callback())); |
| 589 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 572 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 590 | 573 |
| 591 upload_data_stream.AppendChunk(kUploadData, chunk_size, true); | 574 upload_data_stream.AppendChunk(kUploadData, chunk_size, true); |
| 592 | 575 |
| 593 // Ack both packets in the request. | 576 // Ack both packets in the request. |
| 594 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 577 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 595 ProcessPacket(*ack); | |
| 596 | 578 |
| 597 // Send the response headers (but not the body). | 579 // Send the response headers (but not the body). |
| 598 SetResponseString("200 OK", std::string()); | 580 SetResponse("200 OK", std::string()); |
| 599 scoped_ptr<QuicEncryptedPacket> resp( | 581 if (GetParam() > QUIC_VERSION_12) { |
| 600 ConstructDataPacket(2, false, !kFin, 0, response_data_)); | 582 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); |
| 601 ProcessPacket(*resp); | 583 } else { |
| 584 ProcessPacket(ConstructDataPacket(2, false, !kFin, 0, response_data_)); |
| 585 } |
| 602 | 586 |
| 603 // Since the headers have already arrived, this should return immediately. | 587 // Since the headers have already arrived, this should return immediately. |
| 604 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); | 588 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); |
| 605 ASSERT_TRUE(response_.headers.get()); | 589 ASSERT_TRUE(response_.headers.get()); |
| 606 EXPECT_EQ(200, response_.headers->response_code()); | 590 EXPECT_EQ(200, response_.headers->response_code()); |
| 607 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); | 591 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); |
| 608 | 592 |
| 609 // Send the response body. | 593 // Send the response body. |
| 610 const char kResponseBody[] = "Hello world!"; | 594 const char kResponseBody[] = "Hello world!"; |
| 611 scoped_ptr<QuicEncryptedPacket> resp_body( | 595 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), |
| 612 ConstructDataPacket(3, false, kFin, response_data_.length(), | 596 kResponseBody)); |
| 613 kResponseBody)); | |
| 614 ProcessPacket(*resp_body); | |
| 615 | 597 |
| 616 // Since the body has already arrived, this should return immediately. | 598 // Since the body has already arrived, this should return immediately. |
| 617 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), | 599 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), |
| 618 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), | 600 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
| 619 callback_.callback())); | 601 callback_.callback())); |
| 620 | 602 |
| 621 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 603 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 622 EXPECT_TRUE(AtEof()); | 604 EXPECT_TRUE(AtEof()); |
| 623 } | 605 } |
| 624 | 606 |
| 625 TEST_F(QuicHttpStreamTest, DestroyedEarly) { | 607 TEST_P(QuicHttpStreamTest, DestroyedEarly) { |
| 626 SetRequestString("GET", "/", DEFAULT_PRIORITY); | 608 SetRequest("GET", "/", DEFAULT_PRIORITY); |
| 627 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 609 if (GetParam() > QUIC_VERSION_12) { |
| 628 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); | 610 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 611 } else { |
| 612 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 613 } |
| 614 AddWrite(ConstructRstStreamPacket(2)); |
| 629 use_closing_stream_ = true; | 615 use_closing_stream_ = true; |
| 630 Initialize(); | 616 Initialize(); |
| 631 | 617 |
| 632 request_.method = "GET"; | 618 request_.method = "GET"; |
| 633 request_.url = GURL("http://www.google.com/"); | 619 request_.url = GURL("http://www.google.com/"); |
| 634 | 620 |
| 635 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 621 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 636 net_log_, callback_.callback())); | 622 net_log_, callback_.callback())); |
| 637 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 623 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 638 callback_.callback())); | 624 callback_.callback())); |
| 639 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 625 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 640 | 626 |
| 641 // Ack the request. | 627 // Ack the request. |
| 642 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 628 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 643 ProcessPacket(*ack); | |
| 644 EXPECT_EQ(ERR_IO_PENDING, | 629 EXPECT_EQ(ERR_IO_PENDING, |
| 645 stream_->ReadResponseHeaders(callback_.callback())); | 630 stream_->ReadResponseHeaders(callback_.callback())); |
| 646 | 631 |
| 647 // Send the response with a body. | 632 // Send the response with a body. |
| 648 SetResponseString("404 OK", "hello world!"); | 633 SetResponse("404 OK", "hello world!"); |
| 649 scoped_ptr<QuicEncryptedPacket> resp( | |
| 650 ConstructDataPacket(2, false, kFin, 0, response_data_)); | |
| 651 | |
| 652 // In the course of processing this packet, the QuicHttpStream close itself. | 634 // In the course of processing this packet, the QuicHttpStream close itself. |
| 653 ProcessPacket(*resp); | 635 if (GetParam() > QUIC_VERSION_12) { |
| 636 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
| 637 } else { |
| 638 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 639 } |
| 654 | 640 |
| 655 EXPECT_TRUE(AtEof()); | 641 EXPECT_TRUE(AtEof()); |
| 656 } | 642 } |
| 657 | 643 |
| 658 TEST_F(QuicHttpStreamTest, Priority) { | 644 TEST_P(QuicHttpStreamTest, Priority) { |
| 659 SetRequestString("GET", "/", MEDIUM); | 645 SetRequest("GET", "/", MEDIUM); |
| 660 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 646 if (GetParam() > QUIC_VERSION_12) { |
| 661 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); | 647 AddWrite(ConstructRequestHeadersPacket(1, kFin)); |
| 648 } else { |
| 649 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 650 } |
| 651 AddWrite(ConstructRstStreamPacket(2)); |
| 662 use_closing_stream_ = true; | 652 use_closing_stream_ = true; |
| 663 Initialize(); | 653 Initialize(); |
| 664 | 654 |
| 665 request_.method = "GET"; | 655 request_.method = "GET"; |
| 666 request_.url = GURL("http://www.google.com/"); | 656 request_.url = GURL("http://www.google.com/"); |
| 667 | 657 |
| 668 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, | 658 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
| 669 net_log_, callback_.callback())); | 659 net_log_, callback_.callback())); |
| 670 | 660 |
| 671 // Check that priority is highest. | 661 // Check that priority is highest. |
| 672 QuicReliableClientStream* reliable_stream = | 662 QuicReliableClientStream* reliable_stream = |
| 673 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); | 663 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
| 674 DCHECK(reliable_stream); | 664 DCHECK(reliable_stream); |
| 675 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), | 665 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
| 676 reliable_stream->EffectivePriority()); | 666 reliable_stream->EffectivePriority()); |
| 677 | 667 |
| 678 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 668 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 679 callback_.callback())); | 669 callback_.callback())); |
| 680 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 670 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 681 | 671 |
| 682 // Check that priority has now dropped back to MEDIUM. | 672 // Check that priority has now dropped back to MEDIUM. |
| 683 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( | 673 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( |
| 684 reliable_stream->EffectivePriority())); | 674 reliable_stream->EffectivePriority())); |
| 685 | 675 |
| 686 // Ack the request. | 676 // Ack the request. |
| 687 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 677 ProcessPacket(ConstructAckPacket(1, 0, 0)); |
| 688 ProcessPacket(*ack); | |
| 689 EXPECT_EQ(ERR_IO_PENDING, | 678 EXPECT_EQ(ERR_IO_PENDING, |
| 690 stream_->ReadResponseHeaders(callback_.callback())); | 679 stream_->ReadResponseHeaders(callback_.callback())); |
| 691 | 680 |
| 692 // Send the response with a body. | 681 // Send the response with a body. |
| 693 SetResponseString("404 OK", "hello world!"); | 682 SetResponse("404 OK", "hello world!"); |
| 694 scoped_ptr<QuicEncryptedPacket> resp( | |
| 695 ConstructDataPacket(2, false, kFin, 0, response_data_)); | |
| 696 | |
| 697 // In the course of processing this packet, the QuicHttpStream close itself. | 683 // In the course of processing this packet, the QuicHttpStream close itself. |
| 698 ProcessPacket(*resp); | 684 if (GetParam() > QUIC_VERSION_12) { |
| 685 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); |
| 686 } else { |
| 687 ProcessPacket(ConstructDataPacket(2, !kIncludeVersion, kFin, 0, |
| 688 response_data_)); |
| 689 } |
| 699 | 690 |
| 700 EXPECT_TRUE(AtEof()); | 691 EXPECT_TRUE(AtEof()); |
| 701 } | 692 } |
| 702 | 693 |
| 703 // Regression test for http://crbug.com/294870 | 694 // Regression test for http://crbug.com/294870 |
| 704 TEST_F(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { | 695 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { |
| 705 SetRequestString("GET", "/", MEDIUM); | 696 SetRequest("GET", "/", MEDIUM); |
| 706 use_closing_stream_ = true; | 697 use_closing_stream_ = true; |
| 707 Initialize(); | 698 Initialize(); |
| 708 | 699 |
| 709 request_.method = "GET"; | 700 request_.method = "GET"; |
| 710 request_.url = GURL("http://www.google.com/"); | 701 request_.url = GURL("http://www.google.com/"); |
| 711 | 702 |
| 712 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, | 703 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
| 713 net_log_, callback_.callback())); | 704 net_log_, callback_.callback())); |
| 714 | 705 |
| 715 // Check that priority is highest. | 706 // Check that priority is highest. |
| 716 QuicReliableClientStream* reliable_stream = | 707 QuicReliableClientStream* reliable_stream = |
| 717 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); | 708 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
| 718 DCHECK(reliable_stream); | 709 DCHECK(reliable_stream); |
| 719 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); | 710 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); |
| 720 DCHECK(delegate); | 711 DCHECK(delegate); |
| 721 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), | 712 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
| 722 reliable_stream->EffectivePriority()); | 713 reliable_stream->EffectivePriority()); |
| 723 | 714 |
| 724 // Set Delegate to NULL and make sure EffectivePriority returns highest | 715 // Set Delegate to NULL and make sure EffectivePriority returns highest |
| 725 // priority. | 716 // priority. |
| 726 reliable_stream->SetDelegate(NULL); | 717 reliable_stream->SetDelegate(NULL); |
| 727 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), | 718 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
| 728 reliable_stream->EffectivePriority()); | 719 reliable_stream->EffectivePriority()); |
| 729 reliable_stream->SetDelegate(delegate); | 720 reliable_stream->SetDelegate(delegate); |
| 730 } | 721 } |
| 731 | 722 |
| 732 TEST_F(QuicHttpStreamTest, DontCompressHeadersWhenNotWritable) { | 723 TEST_P(QuicHttpStreamTest, DontCompressHeadersWhenNotWritable) { |
| 733 SetRequestString("GET", "/", MEDIUM); | 724 SetRequest("GET", "/", MEDIUM); |
| 734 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 725 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_)); |
| 726 Initialize(); |
| 735 | 727 |
| 736 Initialize(); | 728 if (GetParam() > QUIC_VERSION_12) { |
| 729 // The behavior tested here is obsolete. |
| 730 return; |
| 731 } |
| 737 request_.method = "GET"; | 732 request_.method = "GET"; |
| 738 request_.url = GURL("http://www.google.com/"); | 733 request_.url = GURL("http://www.google.com/"); |
| 739 | 734 |
| 740 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 735 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
| 741 WillRepeatedly(Return(QuicTime::Delta::Infinite())); | 736 WillRepeatedly(Return(QuicTime::Delta::Infinite())); |
| 742 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, | 737 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
| 743 net_log_, callback_.callback())); | 738 net_log_, callback_.callback())); |
| 744 EXPECT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, | 739 EXPECT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, |
| 745 callback_.callback())); | 740 callback_.callback())); |
| 746 | 741 |
| 747 // Verify that the headers have not been compressed and buffered in | 742 // Verify that the headers have not been compressed and buffered in |
| 748 // the stream. | 743 // the stream. |
| 749 QuicReliableClientStream* reliable_stream = | 744 QuicReliableClientStream* reliable_stream = |
| 750 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); | 745 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
| 751 EXPECT_FALSE(reliable_stream->HasBufferedData()); | 746 EXPECT_FALSE(reliable_stream->HasBufferedData()); |
| 752 EXPECT_FALSE(AtEof()); | 747 EXPECT_FALSE(AtEof()); |
| 753 | 748 |
| 754 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 749 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
| 755 WillRepeatedly(Return(QuicTime::Delta::Zero())); | 750 WillRepeatedly(Return(QuicTime::Delta::Zero())); |
| 756 | 751 |
| 757 // Data should flush out now. | 752 // Data should flush out now. |
| 758 connection_->OnCanWrite(); | 753 connection_->OnCanWrite(); |
| 759 EXPECT_FALSE(reliable_stream->HasBufferedData()); | 754 EXPECT_FALSE(reliable_stream->HasBufferedData()); |
| 760 EXPECT_TRUE(AtEof()); | 755 EXPECT_TRUE(AtEof()); |
| 761 } | 756 } |
| 762 | 757 |
| 763 } // namespace test | 758 } // namespace test |
| 764 | |
| 765 } // namespace net | 759 } // namespace net |
| OLD | NEW |