blob: 75e533ca4f89abce97925049be79da764f5d3aa9 [file] [log] [blame]
[email protected]f702d572012-12-04 15:56:201// 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
3// found in the LICENSE file.
4
5#include "net/quic/quic_http_stream.h"
6
7#include <vector>
8
9#include "net/base/net_errors.h"
10#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0611#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2012#include "net/base/upload_data_stream.h"
13#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1514#include "net/http/transport_security_state.h"
[email protected]fee17f72013-02-03 07:47:4115#include "net/quic/congestion_control/receive_algorithm_interface.h"
16#include "net/quic/congestion_control/send_algorithm_interface.h"
[email protected]e8ff26842013-03-22 21:02:0517#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1618#include "net/quic/crypto/quic_decrypter.h"
19#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0420#include "net/quic/crypto/quic_server_info.h"
[email protected]f702d572012-12-04 15:56:2021#include "net/quic/quic_client_session.h"
22#include "net/quic/quic_connection.h"
23#include "net/quic/quic_connection_helper.h"
[email protected]cbd731e2013-10-24 00:20:3924#include "net/quic/quic_default_packet_writer.h"
[email protected]24e5bc52013-09-18 15:36:5825#include "net/quic/quic_http_utils.h"
26#include "net/quic/quic_reliable_client_stream.h"
[email protected]9f0dcd4e2014-01-16 15:58:1427#include "net/quic/quic_write_blocked_list.h"
[email protected]3e7dca62013-09-10 16:14:2328#include "net/quic/spdy_utils.h"
[email protected]f702d572012-12-04 15:56:2029#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0530#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0331#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3932#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2033#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2034#include "net/quic/test_tools/quic_test_utils.h"
35#include "net/quic/test_tools/test_task_runner.h"
36#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3637#include "net/spdy/spdy_frame_builder.h"
38#include "net/spdy/spdy_framer.h"
39#include "net/spdy/spdy_http_utils.h"
40#include "net/spdy/spdy_protocol.h"
[email protected]f702d572012-12-04 15:56:2041#include "testing/gmock/include/gmock/gmock.h"
42#include "testing/gtest/include/gtest/gtest.h"
43
44using testing::_;
[email protected]06ff5152013-08-29 01:03:0545using testing::AnyNumber;
46using testing::Return;
[email protected]f702d572012-12-04 15:56:2047
48namespace net {
[email protected]f702d572012-12-04 15:56:2049namespace test {
[email protected]f702d572012-12-04 15:56:2050namespace {
51
[email protected]16ba7742014-08-22 00:57:2552const char kUploadData[] = "Really nifty data!";
[email protected]e4c3ea62014-03-15 00:45:1453const char kServerHostname[] = "www.google.com";
54const uint16 kServerPort = 80;
[email protected]f702d572012-12-04 15:56:2055
56class TestQuicConnection : public QuicConnection {
57 public:
[email protected]1e960032013-12-20 19:00:2058 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4359 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2060 IPEndPoint address,
[email protected]cbd731e2013-10-24 00:20:3961 QuicConnectionHelper* helper,
[email protected]6d515822014-08-22 01:58:0662 const QuicConnection::PacketWriterFactory& writer_factory)
[email protected]66cd2d62014-08-01 18:42:3963 : QuicConnection(connection_id,
64 address,
65 helper,
[email protected]6d515822014-08-22 01:58:0666 writer_factory,
67 true /* owns_writer */,
[email protected]66cd2d62014-08-01 18:42:3968 false /* is_server */,
[email protected]ce7bb1412014-05-17 15:51:3369 versions) {
[email protected]f702d572012-12-04 15:56:2070 }
71
[email protected]fee17f72013-02-03 07:47:4172 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
73 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2074 }
[email protected]26f3f8e2012-12-13 21:07:1975
[email protected]fee17f72013-02-03 07:47:4176 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
77 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
[email protected]26f3f8e2012-12-13 21:07:1978 }
79};
80
[email protected]fee17f72013-02-03 07:47:4181class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
[email protected]26f3f8e2012-12-13 21:07:1982 public:
[email protected]1e960032013-12-20 19:00:2083 virtual bool GenerateCongestionFeedback(
84 QuicCongestionFeedbackFrame* /*congestion_feedback*/) {
85 return false;
[email protected]26f3f8e2012-12-13 21:07:1986 }
87
[email protected]6ae6e342014-02-06 02:21:4288 MOCK_METHOD3(RecordIncomingPacket,
89 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime));
[email protected]f702d572012-12-04 15:56:2090};
91
[email protected]63534512012-12-23 18:49:0092// Subclass of QuicHttpStream that closes itself when the first piece of data
93// is received.
94class AutoClosingStream : public QuicHttpStream {
95 public:
[email protected]0b2294d32013-08-02 00:46:3696 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
97 : QuicHttpStream(session) {
[email protected]63534512012-12-23 18:49:0098 }
99
[email protected]46fadfd2013-02-06 09:40:16100 virtual int OnDataReceived(const char* data, int length) OVERRIDE {
[email protected]63534512012-12-23 18:49:00101 Close(false);
102 return OK;
103 }
104};
105
[email protected]6d515822014-08-22 01:58:06106class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
107 public:
108 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
109 : socket_(socket) {}
110 virtual ~TestPacketWriterFactory() {}
111
112 virtual QuicPacketWriter* Create(QuicConnection* connection) const OVERRIDE {
113 return new QuicDefaultPacketWriter(socket_);
114 }
115
116 private:
117 DatagramClientSocket* socket_;
118};
119
[email protected]f702d572012-12-04 15:56:20120} // namespace
121
[email protected]24e5bc52013-09-18 15:36:58122class QuicHttpStreamPeer {
123 public:
124 static QuicReliableClientStream* GetQuicReliableClientStream(
125 QuicHttpStream* stream) {
126 return stream->stream_;
127 }
128};
129
[email protected]1e960032013-12-20 19:00:20130class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20131 protected:
[email protected]1e960032013-12-20 19:00:20132 static const bool kFin = true;
133 static const bool kIncludeVersion = true;
134 static const bool kIncludeCongestionFeedback = true;
135
[email protected]f702d572012-12-04 15:56:20136 // Holds a packet to be written to the wire, and the IO mode that should
137 // be used by the mock socket when performing the write.
138 struct PacketToWrite {
139 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
140 : mode(mode),
141 packet(packet) {
142 }
143 IoMode mode;
144 QuicEncryptedPacket* packet;
145 };
146
147 QuicHttpStreamTest()
148 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00149 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20150 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43151 connection_id_(2),
[email protected]66ae5962014-05-22 11:13:05152 stream_id_(kClientDataStreamId1),
rtenneti4b06ae72014-08-26 03:43:43153 maker_(GetParam(), connection_id_, &clock_),
[email protected]1e960032013-12-20 19:00:20154 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20155 IPAddressNumber ip;
156 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
157 peer_addr_ = IPEndPoint(ip, 443);
158 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43159 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20160 }
161
162 ~QuicHttpStreamTest() {
[email protected]4d283b32013-10-17 12:57:27163 session_->CloseSessionOnError(ERR_ABORTED);
[email protected]f702d572012-12-04 15:56:20164 for (size_t i = 0; i < writes_.size(); i++) {
165 delete writes_[i].packet;
166 }
167 }
168
169 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20170 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
171 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20172 }
173
174 // Returns the packet to be written at position |pos|.
175 QuicEncryptedPacket* GetWrite(size_t pos) {
176 return writes_[pos].packet;
177 }
178
179 bool AtEof() {
180 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
181 }
182
[email protected]1e960032013-12-20 19:00:20183 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
184 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20185 }
186
187 // Configures the test fixture to use the list of expected writes.
188 void Initialize() {
189 mock_writes_.reset(new MockWrite[writes_.size()]);
190 for (size_t i = 0; i < writes_.size(); i++) {
191 mock_writes_[i] = MockWrite(writes_[i].mode,
192 writes_[i].packet->data(),
193 writes_[i].packet->length());
194 };
195
196 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
197 writes_.size()));
198
[email protected]e13201d82012-12-12 05:00:32199 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
200 net_log_.net_log());
201 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20202 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41203 send_algorithm_ = new MockSendAlgorithm();
[email protected]1e960032013-12-20 19:00:20204 receive_algorithm_ = new TestReceiveAlgorithm();
[email protected]6ae6e342014-02-06 02:21:42205 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05206 Times(AnyNumber());
[email protected]efecff92013-09-24 07:49:23207 EXPECT_CALL(*send_algorithm_,
[email protected]ef0da582014-05-09 07:16:30208 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
[email protected]48878092013-07-26 14:51:56209 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05210 Return(QuicTime::Delta::Zero()));
[email protected]08da9adb2014-04-24 08:33:31211 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
212 Return(kMaxPacketSize));
[email protected]77b5d50b2014-05-07 22:48:48213 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05214 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45215 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05216 Return(QuicBandwidth::Zero()));
[email protected]62f90632013-11-01 13:07:11217 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44218 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
219 &random_generator_));
[email protected]6d515822014-08-22 01:58:06220 TestPacketWriterFactory writer_factory(socket);
[email protected]3aa9ca72014-02-27 19:39:43221 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
222 connection_id_, peer_addr_,
[email protected]6d515822014-08-22 01:58:06223 helper_.get(), writer_factory);
[email protected]f702d572012-12-04 15:56:20224 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41225 connection_->SetSendAlgorithm(send_algorithm_);
226 connection_->SetReceiveAlgorithm(receive_algorithm_);
[email protected]ef95114d2013-04-17 17:57:01227 crypto_config_.SetDefaults();
[email protected]18ccfdb2013-08-15 00:13:44228 session_.reset(
229 new QuicClientSession(connection_,
[email protected]cbd731e2013-10-24 00:20:39230 scoped_ptr<DatagramClientSocket>(socket),
[email protected]6d515822014-08-22 01:58:06231 NULL,
[email protected]5db452202014-08-19 05:22:15232 &transport_security_state_,
[email protected]89f79a42014-03-19 11:30:01233 make_scoped_ptr((QuicServerInfo*)NULL),
rtennetib998b322014-08-26 00:36:33234 DefaultQuicConfig(),
[email protected]65768442014-06-06 23:37:03235 base::MessageLoop::current()->
236 message_loop_proxy().get(),
[email protected]ce7bb1412014-05-17 15:51:33237 NULL));
rtennetib998b322014-08-26 00:36:33238 session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
239 false, PRIVACY_MODE_DISABLED),
240 &crypto_config_,
241 &crypto_client_stream_factory_);
[email protected]ed3fc15d2013-03-08 18:37:44242 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48243 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36244 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36245 new AutoClosingStream(session_->GetWeakPtr()) :
246 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36247 }
248
[email protected]1e960032013-12-20 19:00:20249 void SetRequest(const std::string& method,
250 const std::string& path,
251 RequestPriority priority) {
252 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36253 }
254
[email protected]1e960032013-12-20 19:00:20255 void SetResponse(const std::string& status, const std::string& body) {
256 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03257 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36258 }
[email protected]f702d572012-12-04 15:56:20259
[email protected]1e960032013-12-20 19:00:20260 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]f702d572012-12-04 15:56:20261 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05262 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20263 bool fin,
264 QuicStreamOffset offset,
265 base::StringPiece data) {
[email protected]1e960032013-12-20 19:00:20266 return maker_.MakeDataPacket(
267 sequence_number, stream_id_, should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20268 }
269
[email protected]1e960032013-12-20 19:00:20270 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
271 QuicPacketSequenceNumber sequence_number,
272 bool fin) {
273 return maker_.MakeRequestHeadersPacket(
274 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_);
275 }
276
277 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
278 QuicPacketSequenceNumber sequence_number,
279 bool fin) {
280 return maker_.MakeResponseHeadersPacket(
281 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
282 }
283
284 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
[email protected]06ff5152013-08-29 01:03:05285 QuicPacketSequenceNumber sequence_number) {
[email protected]1e960032013-12-20 19:00:20286 return maker_.MakeRstPacket(
[email protected]51cc1342014-04-18 23:44:37287 sequence_number, true, stream_id_,
288 AdjustErrorForVersion(QUIC_RST_FLOW_CONTROL_ACCOUNTING, GetParam()));
[email protected]06ff5152013-08-29 01:03:05289 }
290
[email protected]c5e1aca2014-01-30 04:03:04291 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
292 QuicPacketSequenceNumber sequence_number) {
293 return maker_.MakeAckAndRstPacket(
294 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
[email protected]08da9adb2014-04-24 08:33:31295 2, 1, !kIncludeCongestionFeedback);
[email protected]c5e1aca2014-01-30 04:03:04296 }
297
[email protected]1e960032013-12-20 19:00:20298 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
[email protected]f702d572012-12-04 15:56:20299 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00300 QuicPacketSequenceNumber largest_received,
301 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20302 return maker_.MakeAckPacket(sequence_number, largest_received,
303 least_unacked, !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00304 }
305
[email protected]f702d572012-12-04 15:56:20306 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00307 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41308 MockSendAlgorithm* send_algorithm_;
309 TestReceiveAlgorithm* receive_algorithm_;
[email protected]f702d572012-12-04 15:56:20310 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17311 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20312 MockClock clock_;
313 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44314 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20315 testing::StrictMock<MockConnectionVisitor> visitor_;
316 scoped_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15317 TransportSecurityState transport_security_state_;
[email protected]f702d572012-12-04 15:56:20318 scoped_ptr<QuicClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01319 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20320 TestCompletionCallback callback_;
321 HttpRequestInfo request_;
322 HttpRequestHeaders headers_;
323 HttpResponseInfo response_;
324 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20325 SpdyHeaderBlock request_headers_;
326 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36327 std::string request_data_;
328 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20329
330 private:
[email protected]3aa9ca72014-02-27 19:39:43331 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20332 const QuicStreamId stream_id_;
333 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20334 IPEndPoint self_addr_;
335 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58336 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05337 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20338 scoped_ptr<StaticSocketDataProvider> socket_data_;
339 std::vector<PacketToWrite> writes_;
340};
341
[email protected]1e960032013-12-20 19:00:20342INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
343 ::testing::ValuesIn(QuicSupportedVersions()));
344
345TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44346 Initialize();
[email protected]f702d572012-12-04 15:56:20347 EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
348}
349
[email protected]1e960032013-12-20 19:00:20350TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44351 Initialize();
[email protected]f702d572012-12-04 15:56:20352 EXPECT_TRUE(stream_->CanFindEndOfResponse());
353}
354
[email protected]1e960032013-12-20 19:00:20355TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44356 Initialize();
[email protected]f702d572012-12-04 15:56:20357 EXPECT_FALSE(stream_->IsConnectionReusable());
358}
359
[email protected]1e960032013-12-20 19:00:20360TEST_P(QuicHttpStreamTest, GetRequest) {
361 SetRequest("GET", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03362 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]f702d572012-12-04 15:56:20363 Initialize();
364
365 request_.method = "GET";
366 request_.url = GURL("http://www.google.com/");
367
[email protected]262eec82013-03-19 21:01:36368 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
369 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20370 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
371 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20372
373 // Ack the request.
[email protected]1e960032013-12-20 19:00:20374 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20375
376 EXPECT_EQ(ERR_IO_PENDING,
377 stream_->ReadResponseHeaders(callback_.callback()));
378
[email protected]1e960032013-12-20 19:00:20379 SetResponse("404 Not Found", std::string());
[email protected]92bf17c2014-03-03 21:14:03380 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]f702d572012-12-04 15:56:20381
382 // Now that the headers have been processed, the callback will return.
383 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36384 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20385 EXPECT_EQ(404, response_.headers->response_code());
386 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53387 EXPECT_FALSE(response_.response_time.is_null());
388 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20389
390 // There is no body, so this should return immediately.
391 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
392 read_buffer_->size(),
393 callback_.callback()));
394 EXPECT_TRUE(stream_->IsResponseBodyComplete());
395 EXPECT_TRUE(AtEof());
396}
397
[email protected]3e7dca62013-09-10 16:14:23398// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20399TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
400 SetRequest("GET", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03401 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]3e7dca62013-09-10 16:14:23402 Initialize();
403
404 request_.method = "GET";
405 request_.url = GURL("http://www.google.com/");
406
407 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
408 net_log_, callback_.callback()));
409 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
410 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23411
412 // Ack the request.
[email protected]1e960032013-12-20 19:00:20413 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23414
415 EXPECT_EQ(ERR_IO_PENDING,
416 stream_->ReadResponseHeaders(callback_.callback()));
417
418 SpdyHeaderBlock headers;
419 headers[":status"] = "200 OK";
420 headers[":version"] = "HTTP/1.1";
421 headers["content-type"] = "text/plain";
422 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
423
424 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
425 EXPECT_LT(4096u, response.length());
426 stream_->OnDataReceived(response.data(), response.length());
427 stream_->OnClose(QUIC_NO_ERROR);
428
429 // Now that the headers have been processed, the callback will return.
430 EXPECT_EQ(OK, callback_.WaitForResult());
431 ASSERT_TRUE(response_.headers.get());
432 EXPECT_EQ(200, response_.headers->response_code());
433 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
434
435 // There is no body, so this should return immediately.
436 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
437 read_buffer_->size(),
438 callback_.callback()));
439 EXPECT_TRUE(stream_->IsResponseBodyComplete());
440 EXPECT_TRUE(AtEof());
441}
442
[email protected]1e960032013-12-20 19:00:20443TEST_P(QuicHttpStreamTest, SendPostRequest) {
444 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03445 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
446 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20447 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20448
449 Initialize();
450
[email protected]b2d26cfd2012-12-11 10:36:06451 ScopedVector<UploadElementReader> element_readers;
452 element_readers.push_back(
453 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
[email protected]96c77a72013-09-24 09:49:20454 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20455 request_.method = "POST";
456 request_.url = GURL("http://www.google.com/");
457 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24458 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20459
[email protected]262eec82013-03-19 21:01:36460 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
461 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20462 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
463 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20464
465 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20466 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20467
468 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20469 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03470 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]f702d572012-12-04 15:56:20471
472 // Since the headers have already arrived, this should return immediately.
473 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36474 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20475 EXPECT_EQ(200, response_.headers->response_code());
476 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
477
478 // Send the response body.
479 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03480 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20481 // Since the body has already arrived, this should return immediately.
482 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
483 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
484 callback_.callback()));
485
486 EXPECT_TRUE(stream_->IsResponseBodyComplete());
487 EXPECT_TRUE(AtEof());
488}
489
[email protected]1e960032013-12-20 19:00:20490TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
491 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47492 size_t chunk_size = strlen(kUploadData);
[email protected]92bf17c2014-03-03 21:14:03493 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
494 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
495 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
496 kUploadData));
[email protected]1e960032013-12-20 19:00:20497 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47498 Initialize();
499
500 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
501 upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
502
503 request_.method = "POST";
504 request_.url = GURL("http://www.google.com/");
505 request_.upload_data_stream = &upload_data_stream;
506 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
507
[email protected]262eec82013-03-19 21:01:36508 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
509 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47510 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
511 callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47512
513 upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
514
515 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20516 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47517
518 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20519 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03520 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]c9e49a02013-02-26 05:56:47521
522 // Since the headers have already arrived, this should return immediately.
523 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36524 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47525 EXPECT_EQ(200, response_.headers->response_code());
526 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
527
528 // Send the response body.
529 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20530 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
531 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47532
533 // Since the body has already arrived, this should return immediately.
534 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
535 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
536 callback_.callback()));
537
538 EXPECT_TRUE(stream_->IsResponseBodyComplete());
539 EXPECT_TRUE(AtEof());
540}
541
[email protected]16ba7742014-08-22 00:57:25542TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
543 SetRequest("POST", "/", DEFAULT_PRIORITY);
544 size_t chunk_size = strlen(kUploadData);
545 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
546 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
547 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
548 AddWrite(ConstructAckPacket(4, 3, 1));
549 Initialize();
550
551 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
552 upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
553
554 request_.method = "POST";
555 request_.url = GURL("http://www.google.com/");
556 request_.upload_data_stream = &upload_data_stream;
557 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
558
559 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
560 net_log_, callback_.callback()));
561 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
562 callback_.callback()));
563
564 upload_data_stream.AppendChunk(NULL, 0, true);
565
566 ProcessPacket(ConstructAckPacket(1, 0, 0));
567
568 // Send the response headers (but not the body).
569 SetResponse("200 OK", std::string());
570 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
571
572 // Since the headers have already arrived, this should return immediately.
573 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
574 ASSERT_TRUE(response_.headers.get());
575 EXPECT_EQ(200, response_.headers->response_code());
576 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
577
578 // Send the response body.
579 const char kResponseBody[] = "Hello world!";
580 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
581 kResponseBody));
582
583 // Since the body has already arrived, this should return immediately.
584 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
585 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
586 callback_.callback()));
587
588 EXPECT_TRUE(stream_->IsResponseBodyComplete());
589 EXPECT_TRUE(AtEof());
590}
591
592TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
593 SetRequest("POST", "/", DEFAULT_PRIORITY);
594 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
595 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
596 AddWrite(ConstructAckPacket(3, 3, 1));
597 Initialize();
598
599 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
600
601 request_.method = "POST";
602 request_.url = GURL("http://www.google.com/");
603 request_.upload_data_stream = &upload_data_stream;
604 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
605
606 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
607 net_log_, callback_.callback()));
608 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
609 callback_.callback()));
610
611 upload_data_stream.AppendChunk(NULL, 0, true);
612
613 ProcessPacket(ConstructAckPacket(1, 0, 0));
614
615 // Send the response headers (but not the body).
616 SetResponse("200 OK", std::string());
617 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
618
619 // Since the headers have already arrived, this should return immediately.
620 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
621 ASSERT_TRUE(response_.headers.get());
622 EXPECT_EQ(200, response_.headers->response_code());
623 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
624
625 // Send the response body.
626 const char kResponseBody[] = "Hello world!";
627 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
628 kResponseBody));
629
630 // Since the body has already arrived, this should return immediately.
631 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
632 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
633 callback_.callback()));
634
635 EXPECT_TRUE(stream_->IsResponseBodyComplete());
636 EXPECT_TRUE(AtEof());
637}
638
[email protected]1e960032013-12-20 19:00:20639TEST_P(QuicHttpStreamTest, DestroyedEarly) {
640 SetRequest("GET", "/", DEFAULT_PRIORITY);
[email protected]92bf17c2014-03-03 21:14:03641 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]c5e1aca2014-01-30 04:03:04642 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00643 use_closing_stream_ = true;
644 Initialize();
645
646 request_.method = "GET";
647 request_.url = GURL("http://www.google.com/");
648
[email protected]262eec82013-03-19 21:01:36649 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
650 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00651 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58652 callback_.callback()));
[email protected]63534512012-12-23 18:49:00653
654 // Ack the request.
[email protected]1e960032013-12-20 19:00:20655 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00656 EXPECT_EQ(ERR_IO_PENDING,
657 stream_->ReadResponseHeaders(callback_.callback()));
658
659 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20660 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00661 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03662 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]63534512012-12-23 18:49:00663
664 EXPECT_TRUE(AtEof());
665}
666
[email protected]1e960032013-12-20 19:00:20667TEST_P(QuicHttpStreamTest, Priority) {
668 SetRequest("GET", "/", MEDIUM);
[email protected]92bf17c2014-03-03 21:14:03669 AddWrite(ConstructRequestHeadersPacket(1, kFin));
[email protected]c5e1aca2014-01-30 04:03:04670 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58671 use_closing_stream_ = true;
672 Initialize();
673
674 request_.method = "GET";
675 request_.url = GURL("http://www.google.com/");
676
677 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
678 net_log_, callback_.callback()));
679
680 // Check that priority is highest.
681 QuicReliableClientStream* reliable_stream =
682 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
683 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14684 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58685 reliable_stream->EffectivePriority());
686
687 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
688 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58689
690 // Check that priority has now dropped back to MEDIUM.
691 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
692 reliable_stream->EffectivePriority()));
693
694 // Ack the request.
[email protected]1e960032013-12-20 19:00:20695 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58696 EXPECT_EQ(ERR_IO_PENDING,
697 stream_->ReadResponseHeaders(callback_.callback()));
698
699 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20700 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58701 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03702 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]24e5bc52013-09-18 15:36:58703
704 EXPECT_TRUE(AtEof());
705}
706
[email protected]e1cca9a2013-09-20 17:14:44707// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20708TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
709 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44710 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52711
[email protected]08da9adb2014-04-24 08:33:31712 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52713
[email protected]e1cca9a2013-09-20 17:14:44714 Initialize();
715
716 request_.method = "GET";
717 request_.url = GURL("http://www.google.com/");
718
719 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
720 net_log_, callback_.callback()));
721
722 // Check that priority is highest.
723 QuicReliableClientStream* reliable_stream =
724 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
725 DCHECK(reliable_stream);
726 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
727 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14728 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44729 reliable_stream->EffectivePriority());
730
731 // Set Delegate to NULL and make sure EffectivePriority returns highest
732 // priority.
733 reliable_stream->SetDelegate(NULL);
[email protected]9f0dcd4e2014-01-16 15:58:14734 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44735 reliable_stream->EffectivePriority());
736 reliable_stream->SetDelegate(delegate);
737}
738
[email protected]f702d572012-12-04 15:56:20739} // namespace test
[email protected]f702d572012-12-04 15:56:20740} // namespace net