blob: ff091648d243489ac8c0f7f9bea3742cbc14d868 [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]fee17f72013-02-03 07:47:4114#include "net/quic/congestion_control/receive_algorithm_interface.h"
15#include "net/quic/congestion_control/send_algorithm_interface.h"
[email protected]e8ff26842013-03-22 21:02:0516#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1617#include "net/quic/crypto/quic_decrypter.h"
18#include "net/quic/crypto/quic_encrypter.h"
[email protected]f702d572012-12-04 15:56:2019#include "net/quic/quic_client_session.h"
20#include "net/quic/quic_connection.h"
21#include "net/quic/quic_connection_helper.h"
[email protected]cbd731e2013-10-24 00:20:3922#include "net/quic/quic_default_packet_writer.h"
[email protected]24e5bc52013-09-18 15:36:5823#include "net/quic/quic_http_utils.h"
24#include "net/quic/quic_reliable_client_stream.h"
[email protected]9f0dcd4e2014-01-16 15:58:1425#include "net/quic/quic_write_blocked_list.h"
[email protected]3e7dca62013-09-10 16:14:2326#include "net/quic/spdy_utils.h"
[email protected]f702d572012-12-04 15:56:2027#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0528#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0329#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3930#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2031#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2032#include "net/quic/test_tools/quic_test_utils.h"
33#include "net/quic/test_tools/test_task_runner.h"
34#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3635#include "net/spdy/spdy_frame_builder.h"
36#include "net/spdy/spdy_framer.h"
37#include "net/spdy/spdy_http_utils.h"
38#include "net/spdy/spdy_protocol.h"
[email protected]f702d572012-12-04 15:56:2039#include "testing/gmock/include/gmock/gmock.h"
40#include "testing/gtest/include/gtest/gtest.h"
41
42using testing::_;
[email protected]06ff5152013-08-29 01:03:0543using testing::AnyNumber;
44using testing::Return;
[email protected]f702d572012-12-04 15:56:2045
46namespace net {
[email protected]f702d572012-12-04 15:56:2047namespace test {
[email protected]f702d572012-12-04 15:56:2048namespace {
49
50const char kUploadData[] = "hello world!";
51
52class TestQuicConnection : public QuicConnection {
53 public:
[email protected]1e960032013-12-20 19:00:2054 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4355 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2056 IPEndPoint address,
[email protected]cbd731e2013-10-24 00:20:3957 QuicConnectionHelper* helper,
58 QuicPacketWriter* writer)
[email protected]3aa9ca72014-02-27 19:39:4359 : QuicConnection(connection_id, address, helper, writer, false,
60 versions) {
[email protected]f702d572012-12-04 15:56:2061 }
62
[email protected]fee17f72013-02-03 07:47:4163 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
64 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2065 }
[email protected]26f3f8e2012-12-13 21:07:1966
[email protected]fee17f72013-02-03 07:47:4167 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) {
68 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm);
[email protected]26f3f8e2012-12-13 21:07:1969 }
70};
71
[email protected]fee17f72013-02-03 07:47:4172class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
[email protected]26f3f8e2012-12-13 21:07:1973 public:
[email protected]1e960032013-12-20 19:00:2074 virtual bool GenerateCongestionFeedback(
75 QuicCongestionFeedbackFrame* /*congestion_feedback*/) {
76 return false;
[email protected]26f3f8e2012-12-13 21:07:1977 }
78
[email protected]6ae6e342014-02-06 02:21:4279 MOCK_METHOD3(RecordIncomingPacket,
80 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime));
[email protected]f702d572012-12-04 15:56:2081};
82
[email protected]63534512012-12-23 18:49:0083// Subclass of QuicHttpStream that closes itself when the first piece of data
84// is received.
85class AutoClosingStream : public QuicHttpStream {
86 public:
[email protected]0b2294d32013-08-02 00:46:3687 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
88 : QuicHttpStream(session) {
[email protected]63534512012-12-23 18:49:0089 }
90
[email protected]46fadfd2013-02-06 09:40:1691 virtual int OnDataReceived(const char* data, int length) OVERRIDE {
[email protected]63534512012-12-23 18:49:0092 Close(false);
93 return OK;
94 }
95};
96
[email protected]f702d572012-12-04 15:56:2097} // namespace
98
[email protected]24e5bc52013-09-18 15:36:5899class QuicHttpStreamPeer {
100 public:
101 static QuicReliableClientStream* GetQuicReliableClientStream(
102 QuicHttpStream* stream) {
103 return stream->stream_;
104 }
105};
106
[email protected]1e960032013-12-20 19:00:20107class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20108 protected:
[email protected]1e960032013-12-20 19:00:20109 static const bool kFin = true;
110 static const bool kIncludeVersion = true;
111 static const bool kIncludeCongestionFeedback = true;
112
[email protected]f702d572012-12-04 15:56:20113 // Holds a packet to be written to the wire, and the IO mode that should
114 // be used by the mock socket when performing the write.
115 struct PacketToWrite {
116 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
117 : mode(mode),
118 packet(packet) {
119 }
120 IoMode mode;
121 QuicEncryptedPacket* packet;
122 };
123
124 QuicHttpStreamTest()
125 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00126 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20127 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43128 connection_id_(2),
[email protected]1e960032013-12-20 19:00:20129 stream_id_(GetParam() > QUIC_VERSION_12 ? 5 : 3),
[email protected]3aa9ca72014-02-27 19:39:43130 maker_(GetParam(), connection_id_),
[email protected]1e960032013-12-20 19:00:20131 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20132 IPAddressNumber ip;
133 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
134 peer_addr_ = IPEndPoint(ip, 443);
135 self_addr_ = IPEndPoint(ip, 8435);
[email protected]f702d572012-12-04 15:56:20136 }
137
138 ~QuicHttpStreamTest() {
[email protected]4d283b32013-10-17 12:57:27139 session_->CloseSessionOnError(ERR_ABORTED);
[email protected]f702d572012-12-04 15:56:20140 for (size_t i = 0; i < writes_.size(); i++) {
141 delete writes_[i].packet;
142 }
143 }
144
145 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20146 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
147 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20148 }
149
150 // Returns the packet to be written at position |pos|.
151 QuicEncryptedPacket* GetWrite(size_t pos) {
152 return writes_[pos].packet;
153 }
154
155 bool AtEof() {
156 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
157 }
158
[email protected]1e960032013-12-20 19:00:20159 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
160 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20161 }
162
163 // Configures the test fixture to use the list of expected writes.
164 void Initialize() {
165 mock_writes_.reset(new MockWrite[writes_.size()]);
166 for (size_t i = 0; i < writes_.size(); i++) {
167 mock_writes_[i] = MockWrite(writes_[i].mode,
168 writes_[i].packet->data(),
169 writes_[i].packet->length());
170 };
171
172 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(),
173 writes_.size()));
174
[email protected]e13201d82012-12-12 05:00:32175 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
176 net_log_.net_log());
177 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20178 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41179 send_algorithm_ = new MockSendAlgorithm();
[email protected]1e960032013-12-20 19:00:20180 receive_algorithm_ = new TestReceiveAlgorithm();
[email protected]6ae6e342014-02-06 02:21:42181 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05182 Times(AnyNumber());
[email protected]efecff92013-09-24 07:49:23183 EXPECT_CALL(*send_algorithm_,
[email protected]c0680202013-12-18 04:52:34184 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
[email protected]48878092013-07-26 14:51:56185 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05186 Return(QuicTime::Delta::Zero()));
[email protected]575cce62013-08-03 02:06:43187 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
[email protected]06ff5152013-08-29 01:03:05188 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45189 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05190 Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45191 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05192 Return(QuicBandwidth::Zero()));
[email protected]62f90632013-11-01 13:07:11193 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44194 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
195 &random_generator_));
[email protected]cbd731e2013-10-24 00:20:39196 writer_.reset(new QuicDefaultPacketWriter(socket));
[email protected]3aa9ca72014-02-27 19:39:43197 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
198 connection_id_, peer_addr_,
199 helper_.get(), writer_.get());
[email protected]f702d572012-12-04 15:56:20200 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41201 connection_->SetSendAlgorithm(send_algorithm_);
202 connection_->SetReceiveAlgorithm(receive_algorithm_);
[email protected]ef95114d2013-04-17 17:57:01203 crypto_config_.SetDefaults();
[email protected]18ccfdb2013-08-15 00:13:44204 session_.reset(
205 new QuicClientSession(connection_,
[email protected]cbd731e2013-10-24 00:20:39206 scoped_ptr<DatagramClientSocket>(socket),
207 writer_.Pass(), NULL,
[email protected]18ccfdb2013-08-15 00:13:44208 &crypto_client_stream_factory_,
209 "www.google.com", DefaultQuicConfig(),
210 &crypto_config_, NULL));
[email protected]ed3fc15d2013-03-08 18:37:44211 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48212 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36213 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36214 new AutoClosingStream(session_->GetWeakPtr()) :
215 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36216 }
217
[email protected]1e960032013-12-20 19:00:20218 void SetRequest(const std::string& method,
219 const std::string& path,
220 RequestPriority priority) {
221 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
222 request_data_ = GetParam() > QUIC_VERSION_12 ? "" :
223 SerializeHeaderBlock(request_headers_, true, priority);
[email protected]6cca996b2013-01-25 07:43:36224 }
225
[email protected]1e960032013-12-20 19:00:20226 void SetResponse(const std::string& status, const std::string& body) {
227 response_headers_ = maker_.GetResponseHeaders(status);
228 if (GetParam() > QUIC_VERSION_12) {
229 response_data_ = body;
230 } else {
231 response_data_ =
232 SerializeHeaderBlock(response_headers_, false, DEFAULT_PRIORITY) +
233 body;
[email protected]8edeb8d2013-08-28 06:11:43234 }
[email protected]6cca996b2013-01-25 07:43:36235 }
[email protected]f702d572012-12-04 15:56:20236
[email protected]1e960032013-12-20 19:00:20237 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]f702d572012-12-04 15:56:20238 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05239 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20240 bool fin,
241 QuicStreamOffset offset,
242 base::StringPiece data) {
[email protected]1e960032013-12-20 19:00:20243 return maker_.MakeDataPacket(
244 sequence_number, stream_id_, should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20245 }
246
[email protected]1e960032013-12-20 19:00:20247 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
248 QuicPacketSequenceNumber sequence_number,
249 bool fin) {
250 return maker_.MakeRequestHeadersPacket(
251 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_);
252 }
253
254 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
255 QuicPacketSequenceNumber sequence_number,
256 bool fin) {
257 return maker_.MakeResponseHeadersPacket(
258 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
259 }
260
261 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
[email protected]06ff5152013-08-29 01:03:05262 QuicPacketSequenceNumber sequence_number) {
[email protected]1e960032013-12-20 19:00:20263 return maker_.MakeRstPacket(
[email protected]459a7402014-02-10 12:58:52264 sequence_number, true, stream_id_, QUIC_STREAM_NO_ERROR);
[email protected]06ff5152013-08-29 01:03:05265 }
266
[email protected]c5e1aca2014-01-30 04:03:04267 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
268 QuicPacketSequenceNumber sequence_number) {
269 return maker_.MakeAckAndRstPacket(
270 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
271 1, 1, !kIncludeCongestionFeedback);
272 }
273
[email protected]1e960032013-12-20 19:00:20274 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
[email protected]f702d572012-12-04 15:56:20275 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00276 QuicPacketSequenceNumber largest_received,
277 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20278 return maker_.MakeAckPacket(sequence_number, largest_received,
279 least_unacked, !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00280 }
281
[email protected]f702d572012-12-04 15:56:20282 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00283 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41284 MockSendAlgorithm* send_algorithm_;
285 TestReceiveAlgorithm* receive_algorithm_;
[email protected]f702d572012-12-04 15:56:20286 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17287 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20288 MockClock clock_;
289 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44290 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20291 testing::StrictMock<MockConnectionVisitor> visitor_;
292 scoped_ptr<QuicHttpStream> stream_;
[email protected]cbd731e2013-10-24 00:20:39293 scoped_ptr<QuicDefaultPacketWriter> writer_;
[email protected]f702d572012-12-04 15:56:20294 scoped_ptr<QuicClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01295 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20296 TestCompletionCallback callback_;
297 HttpRequestInfo request_;
298 HttpRequestHeaders headers_;
299 HttpResponseInfo response_;
300 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20301 SpdyHeaderBlock request_headers_;
302 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36303 std::string request_data_;
304 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20305
306 private:
[email protected]1e960032013-12-20 19:00:20307 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers,
308 bool write_priority,
309 RequestPriority priority) {
310 QuicSpdyCompressor compressor;
311 if (write_priority) {
312 return compressor.CompressHeadersWithPriority(
313 ConvertRequestPriorityToQuicPriority(priority), headers);
314 }
315 return compressor.CompressHeaders(headers);
[email protected]f702d572012-12-04 15:56:20316 }
317
[email protected]3aa9ca72014-02-27 19:39:43318 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20319 const QuicStreamId stream_id_;
320 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20321 IPEndPoint self_addr_;
322 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58323 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05324 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20325 scoped_ptr<StaticSocketDataProvider> socket_data_;
326 std::vector<PacketToWrite> writes_;
327};
328
[email protected]1e960032013-12-20 19:00:20329INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
330 ::testing::ValuesIn(QuicSupportedVersions()));
331
332TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44333 Initialize();
[email protected]f702d572012-12-04 15:56:20334 EXPECT_EQ(NULL, stream_->RenewStreamForAuth());
335}
336
[email protected]1e960032013-12-20 19:00:20337TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44338 Initialize();
[email protected]f702d572012-12-04 15:56:20339 EXPECT_TRUE(stream_->CanFindEndOfResponse());
340}
341
[email protected]1e960032013-12-20 19:00:20342TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44343 Initialize();
[email protected]f702d572012-12-04 15:56:20344 EXPECT_FALSE(stream_->IsConnectionReusable());
345}
346
[email protected]1e960032013-12-20 19:00:20347TEST_P(QuicHttpStreamTest, GetRequest) {
348 SetRequest("GET", "/", DEFAULT_PRIORITY);
349 if (GetParam() > QUIC_VERSION_12) {
350 AddWrite(ConstructRequestHeadersPacket(1, kFin));
351 } else {
352 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_));
353 }
[email protected]f702d572012-12-04 15:56:20354 Initialize();
355
356 request_.method = "GET";
357 request_.url = GURL("http://www.google.com/");
358
[email protected]262eec82013-03-19 21:01:36359 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
360 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20361 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
362 callback_.callback()));
363 EXPECT_EQ(&response_, stream_->GetResponseInfo());
364
365 // Ack the request.
[email protected]1e960032013-12-20 19:00:20366 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20367
368 EXPECT_EQ(ERR_IO_PENDING,
369 stream_->ReadResponseHeaders(callback_.callback()));
370
[email protected]1e960032013-12-20 19:00:20371 SetResponse("404 Not Found", std::string());
372 if (GetParam() > QUIC_VERSION_12) {
373 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
374 } else {
375 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_));
376 }
[email protected]f702d572012-12-04 15:56:20377
378 // Now that the headers have been processed, the callback will return.
379 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36380 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20381 EXPECT_EQ(404, response_.headers->response_code());
382 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
383
384 // There is no body, so this should return immediately.
385 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
386 read_buffer_->size(),
387 callback_.callback()));
388 EXPECT_TRUE(stream_->IsResponseBodyComplete());
389 EXPECT_TRUE(AtEof());
390}
391
[email protected]3e7dca62013-09-10 16:14:23392// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20393TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
394 SetRequest("GET", "/", DEFAULT_PRIORITY);
395 if (GetParam() > QUIC_VERSION_12) {
396 AddWrite(ConstructRequestHeadersPacket(1, kFin));
397 } else {
398 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_));
399 }
[email protected]3e7dca62013-09-10 16:14:23400 Initialize();
401
402 request_.method = "GET";
403 request_.url = GURL("http://www.google.com/");
404
405 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
406 net_log_, callback_.callback()));
407 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
408 callback_.callback()));
409 EXPECT_EQ(&response_, stream_->GetResponseInfo());
410
411 // Ack the request.
[email protected]1e960032013-12-20 19:00:20412 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23413
414 EXPECT_EQ(ERR_IO_PENDING,
415 stream_->ReadResponseHeaders(callback_.callback()));
416
417 SpdyHeaderBlock headers;
418 headers[":status"] = "200 OK";
419 headers[":version"] = "HTTP/1.1";
420 headers["content-type"] = "text/plain";
421 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
422
423 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
424 EXPECT_LT(4096u, response.length());
425 stream_->OnDataReceived(response.data(), response.length());
426 stream_->OnClose(QUIC_NO_ERROR);
427
428 // Now that the headers have been processed, the callback will return.
429 EXPECT_EQ(OK, callback_.WaitForResult());
430 ASSERT_TRUE(response_.headers.get());
431 EXPECT_EQ(200, response_.headers->response_code());
432 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
433
434 // There is no body, so this should return immediately.
435 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
436 read_buffer_->size(),
437 callback_.callback()));
438 EXPECT_TRUE(stream_->IsResponseBodyComplete());
439 EXPECT_TRUE(AtEof());
440}
441
[email protected]1e960032013-12-20 19:00:20442TEST_P(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) {
443 SetRequest("GET", "/", DEFAULT_PRIORITY);
444 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_));
[email protected]f702d572012-12-04 15:56:20445 Initialize();
446
[email protected]1e960032013-12-20 19:00:20447 if (GetParam() > QUIC_VERSION_12) {
448 // we can't put the request and response into a single frame.
449 return;
450 }
451
[email protected]f702d572012-12-04 15:56:20452 request_.method = "GET";
453 request_.url = GURL("http://www.google.com/");
454
[email protected]262eec82013-03-19 21:01:36455 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
456 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20457 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
458 callback_.callback()));
459 EXPECT_EQ(&response_, stream_->GetResponseInfo());
460
461 // Ack the request.
[email protected]1e960032013-12-20 19:00:20462 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20463
464 EXPECT_EQ(ERR_IO_PENDING,
465 stream_->ReadResponseHeaders(callback_.callback()));
466
467 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20468 SetResponse("200 OK", "hello world!");
469 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_));
[email protected]f702d572012-12-04 15:56:20470
471 // Now that the headers have been processed, the callback will return.
472 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36473 ASSERT_TRUE(response_.headers.get());
[email protected]6cca996b2013-01-25 07:43:36474 EXPECT_EQ(200, response_.headers->response_code());
[email protected]f702d572012-12-04 15:56:20475 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
476
477 // There is no body, so this should return immediately.
478 // Since the body has already arrived, this should return immediately.
479 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(),
480 read_buffer_->size(),
481 callback_.callback()));
482 EXPECT_TRUE(stream_->IsResponseBodyComplete());
483 EXPECT_TRUE(AtEof());
484}
485
[email protected]1e960032013-12-20 19:00:20486TEST_P(QuicHttpStreamTest, SendPostRequest) {
487 SetRequest("POST", "/", DEFAULT_PRIORITY);
488 if (GetParam() > QUIC_VERSION_12) {
489 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
490 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
491 } else {
492 AddWrite(ConstructDataPacket(1, kIncludeVersion, !kFin, 0, request_data_));
493 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin,
494 request_data_.length(), kUploadData));
495 }
496 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20497
498 Initialize();
499
[email protected]b2d26cfd2012-12-11 10:36:06500 ScopedVector<UploadElementReader> element_readers;
501 element_readers.push_back(
502 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
[email protected]96c77a72013-09-24 09:49:20503 UploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20504 request_.method = "POST";
505 request_.url = GURL("http://www.google.com/");
506 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24507 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20508
[email protected]262eec82013-03-19 21:01:36509 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
510 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20511 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
512 callback_.callback()));
513 EXPECT_EQ(&response_, stream_->GetResponseInfo());
514
515 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20516 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20517
518 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20519 SetResponse("200 OK", std::string());
520 if (GetParam() > QUIC_VERSION_12) {
521 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
522 } else {
523 ProcessPacket(ConstructDataPacket(2, false, !kFin, 0, response_data_));
524 }
[email protected]f702d572012-12-04 15:56:20525
526 // Since the headers have already arrived, this should return immediately.
527 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36528 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20529 EXPECT_EQ(200, response_.headers->response_code());
530 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
531
532 // Send the response body.
533 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20534 if (GetParam() > QUIC_VERSION_12) {
535 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
536 } else {
537 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
538 kResponseBody));
539 }
[email protected]f702d572012-12-04 15:56:20540 // Since the body has already arrived, this should return immediately.
541 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
542 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
543 callback_.callback()));
544
545 EXPECT_TRUE(stream_->IsResponseBodyComplete());
546 EXPECT_TRUE(AtEof());
547}
548
[email protected]1e960032013-12-20 19:00:20549TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
550 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47551 size_t chunk_size = strlen(kUploadData);
[email protected]1e960032013-12-20 19:00:20552 if (GetParam() > QUIC_VERSION_12) {
553 AddWrite(ConstructRequestHeadersPacket(1, !kFin));
554 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
555 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
556 kUploadData));
557 } else {
558 AddWrite(ConstructDataPacket(1, kIncludeVersion, !kFin, 0, request_data_));
559 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin,
560 request_data_.length(), kUploadData));
561 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin,
562 request_data_.length() + chunk_size,
563 kUploadData));
564 }
565 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47566 Initialize();
567
568 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
569 upload_data_stream.AppendChunk(kUploadData, chunk_size, false);
570
571 request_.method = "POST";
572 request_.url = GURL("http://www.google.com/");
573 request_.upload_data_stream = &upload_data_stream;
574 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
575
[email protected]262eec82013-03-19 21:01:36576 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
577 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47578 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
579 callback_.callback()));
580 EXPECT_EQ(&response_, stream_->GetResponseInfo());
581
582 upload_data_stream.AppendChunk(kUploadData, chunk_size, true);
583
584 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20585 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47586
587 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20588 SetResponse("200 OK", std::string());
589 if (GetParam() > QUIC_VERSION_12) {
590 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
591 } else {
592 ProcessPacket(ConstructDataPacket(2, false, !kFin, 0, response_data_));
593 }
[email protected]c9e49a02013-02-26 05:56:47594
595 // Since the headers have already arrived, this should return immediately.
596 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36597 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47598 EXPECT_EQ(200, response_.headers->response_code());
599 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
600
601 // Send the response body.
602 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20603 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
604 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47605
606 // Since the body has already arrived, this should return immediately.
607 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
608 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
609 callback_.callback()));
610
611 EXPECT_TRUE(stream_->IsResponseBodyComplete());
612 EXPECT_TRUE(AtEof());
613}
614
[email protected]1e960032013-12-20 19:00:20615TEST_P(QuicHttpStreamTest, DestroyedEarly) {
616 SetRequest("GET", "/", DEFAULT_PRIORITY);
617 if (GetParam() > QUIC_VERSION_12) {
618 AddWrite(ConstructRequestHeadersPacket(1, kFin));
619 } else {
620 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_));
621 }
[email protected]c5e1aca2014-01-30 04:03:04622 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00623 use_closing_stream_ = true;
624 Initialize();
625
626 request_.method = "GET";
627 request_.url = GURL("http://www.google.com/");
628
[email protected]262eec82013-03-19 21:01:36629 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
630 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00631 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58632 callback_.callback()));
[email protected]63534512012-12-23 18:49:00633 EXPECT_EQ(&response_, stream_->GetResponseInfo());
634
635 // Ack the request.
[email protected]1e960032013-12-20 19:00:20636 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00637 EXPECT_EQ(ERR_IO_PENDING,
638 stream_->ReadResponseHeaders(callback_.callback()));
639
640 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20641 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00642 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]1e960032013-12-20 19:00:20643 if (GetParam() > QUIC_VERSION_12) {
644 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
645 } else {
646 ProcessPacket(ConstructDataPacket(2, false, kFin, 0, response_data_));
647 }
[email protected]63534512012-12-23 18:49:00648
649 EXPECT_TRUE(AtEof());
650}
651
[email protected]1e960032013-12-20 19:00:20652TEST_P(QuicHttpStreamTest, Priority) {
653 SetRequest("GET", "/", MEDIUM);
654 if (GetParam() > QUIC_VERSION_12) {
655 AddWrite(ConstructRequestHeadersPacket(1, kFin));
656 } else {
657 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_));
658 }
[email protected]c5e1aca2014-01-30 04:03:04659 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58660 use_closing_stream_ = true;
661 Initialize();
662
663 request_.method = "GET";
664 request_.url = GURL("http://www.google.com/");
665
666 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
667 net_log_, callback_.callback()));
668
669 // Check that priority is highest.
670 QuicReliableClientStream* reliable_stream =
671 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
672 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14673 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58674 reliable_stream->EffectivePriority());
675
676 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
677 callback_.callback()));
678 EXPECT_EQ(&response_, stream_->GetResponseInfo());
679
680 // Check that priority has now dropped back to MEDIUM.
681 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
682 reliable_stream->EffectivePriority()));
683
684 // Ack the request.
[email protected]1e960032013-12-20 19:00:20685 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58686 EXPECT_EQ(ERR_IO_PENDING,
687 stream_->ReadResponseHeaders(callback_.callback()));
688
689 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20690 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58691 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]1e960032013-12-20 19:00:20692 if (GetParam() > QUIC_VERSION_12) {
693 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
694 } else {
695 ProcessPacket(ConstructDataPacket(2, !kIncludeVersion, kFin, 0,
696 response_data_));
697 }
[email protected]24e5bc52013-09-18 15:36:58698
699 EXPECT_TRUE(AtEof());
700}
701
[email protected]e1cca9a2013-09-20 17:14:44702// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20703TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
704 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44705 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52706
707 if (GetParam() > QUIC_VERSION_13) {
708 AddWrite(ConstructRstStreamPacket(1));
709 }
710
[email protected]e1cca9a2013-09-20 17:14:44711 Initialize();
712
713 request_.method = "GET";
714 request_.url = GURL("http://www.google.com/");
715
716 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
717 net_log_, callback_.callback()));
718
719 // Check that priority is highest.
720 QuicReliableClientStream* reliable_stream =
721 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
722 DCHECK(reliable_stream);
723 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
724 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14725 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44726 reliable_stream->EffectivePriority());
727
728 // Set Delegate to NULL and make sure EffectivePriority returns highest
729 // priority.
730 reliable_stream->SetDelegate(NULL);
[email protected]9f0dcd4e2014-01-16 15:58:14731 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44732 reliable_stream->EffectivePriority());
733 reliable_stream->SetDelegate(delegate);
734}
735
[email protected]1e960032013-12-20 19:00:20736TEST_P(QuicHttpStreamTest, DontCompressHeadersWhenNotWritable) {
737 SetRequest("GET", "/", MEDIUM);
738 AddWrite(ConstructDataPacket(1, kIncludeVersion, kFin, 0, request_data_));
[email protected]13428d42013-11-26 18:50:36739 Initialize();
[email protected]1e960032013-12-20 19:00:20740
741 if (GetParam() > QUIC_VERSION_12) {
742 // The behavior tested here is obsolete.
743 return;
744 }
[email protected]13428d42013-11-26 18:50:36745 request_.method = "GET";
746 request_.url = GURL("http://www.google.com/");
747
748 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
749 WillRepeatedly(Return(QuicTime::Delta::Infinite()));
750 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
751 net_log_, callback_.callback()));
752 EXPECT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
753 callback_.callback()));
754
755 // Verify that the headers have not been compressed and buffered in
756 // the stream.
757 QuicReliableClientStream* reliable_stream =
758 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
759 EXPECT_FALSE(reliable_stream->HasBufferedData());
760 EXPECT_FALSE(AtEof());
761
762 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
763 WillRepeatedly(Return(QuicTime::Delta::Zero()));
764
765 // Data should flush out now.
766 connection_->OnCanWrite();
767 EXPECT_FALSE(reliable_stream->HasBufferedData());
768 EXPECT_TRUE(AtEof());
769}
770
[email protected]f702d572012-12-04 15:56:20771} // namespace test
[email protected]f702d572012-12-04 15:56:20772} // namespace net