blob: 37cfdd002d6a005db56fd08ea7fba625f0cd9cc3 [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
mmenkecbc2b712014-10-09 20:29:079#include "net/base/chunked_upload_data_stream.h"
10#include "net/base/elements_upload_data_stream.h"
[email protected]f702d572012-12-04 15:56:2011#include "net/base/net_errors.h"
12#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0613#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2014#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1515#include "net/http/transport_security_state.h"
[email protected]fee17f72013-02-03 07:47:4116#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,
rtenneti6f48aa92015-03-16 02:18:4867 true /* owns_writer */,
68 Perspective::IS_CLIENT,
69 false /* is_secure */,
70 versions) {}
[email protected]f702d572012-12-04 15:56:2071
[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 }
75};
76
[email protected]63534512012-12-23 18:49:0077// Subclass of QuicHttpStream that closes itself when the first piece of data
78// is received.
79class AutoClosingStream : public QuicHttpStream {
80 public:
[email protected]0b2294d32013-08-02 00:46:3681 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
82 : QuicHttpStream(session) {
[email protected]63534512012-12-23 18:49:0083 }
84
dchengb03027d2014-10-21 12:00:2085 int OnDataReceived(const char* data, int length) override {
[email protected]63534512012-12-23 18:49:0086 Close(false);
87 return OK;
88 }
89};
90
[email protected]6d515822014-08-22 01:58:0691class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
92 public:
93 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
94 : socket_(socket) {}
dchengb03027d2014-10-21 12:00:2095 ~TestPacketWriterFactory() override {}
[email protected]6d515822014-08-22 01:58:0696
dchengb03027d2014-10-21 12:00:2097 QuicPacketWriter* Create(QuicConnection* connection) const override {
[email protected]6d515822014-08-22 01:58:0698 return new QuicDefaultPacketWriter(socket_);
99 }
100
101 private:
102 DatagramClientSocket* socket_;
103};
104
[email protected]f702d572012-12-04 15:56:20105} // namespace
106
[email protected]24e5bc52013-09-18 15:36:58107class QuicHttpStreamPeer {
108 public:
109 static QuicReliableClientStream* GetQuicReliableClientStream(
110 QuicHttpStream* stream) {
111 return stream->stream_;
112 }
113};
114
[email protected]1e960032013-12-20 19:00:20115class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20116 protected:
[email protected]1e960032013-12-20 19:00:20117 static const bool kFin = true;
118 static const bool kIncludeVersion = true;
119 static const bool kIncludeCongestionFeedback = true;
120
[email protected]f702d572012-12-04 15:56:20121 // Holds a packet to be written to the wire, and the IO mode that should
122 // be used by the mock socket when performing the write.
123 struct PacketToWrite {
124 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
125 : mode(mode),
126 packet(packet) {
127 }
128 IoMode mode;
129 QuicEncryptedPacket* packet;
130 };
131
132 QuicHttpStreamTest()
133 : net_log_(BoundNetLog()),
[email protected]63534512012-12-23 18:49:00134 use_closing_stream_(false),
[email protected]f702d572012-12-04 15:56:20135 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43136 connection_id_(2),
[email protected]66ae5962014-05-22 11:13:05137 stream_id_(kClientDataStreamId1),
rtenneti4b06ae72014-08-26 03:43:43138 maker_(GetParam(), connection_id_, &clock_),
[email protected]1e960032013-12-20 19:00:20139 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20140 IPAddressNumber ip;
141 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
142 peer_addr_ = IPEndPoint(ip, 443);
143 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43144 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20145 }
146
147 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19148 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20149 for (size_t i = 0; i < writes_.size(); i++) {
150 delete writes_[i].packet;
151 }
152 }
153
154 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20155 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
156 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20157 }
158
159 // Returns the packet to be written at position |pos|.
160 QuicEncryptedPacket* GetWrite(size_t pos) {
161 return writes_[pos].packet;
162 }
163
164 bool AtEof() {
165 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
166 }
167
[email protected]1e960032013-12-20 19:00:20168 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
169 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20170 }
171
172 // Configures the test fixture to use the list of expected writes.
173 void Initialize() {
174 mock_writes_.reset(new MockWrite[writes_.size()]);
175 for (size_t i = 0; i < writes_.size(); i++) {
176 mock_writes_[i] = MockWrite(writes_[i].mode,
177 writes_[i].packet->data(),
178 writes_[i].packet->length());
179 };
180
rtennetibe635732014-10-02 22:51:42181 socket_data_.reset(new StaticSocketDataProvider(
182 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20183
[email protected]e13201d82012-12-12 05:00:32184 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
185 net_log_.net_log());
186 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20187 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41188 send_algorithm_ = new MockSendAlgorithm();
[email protected]efecff92013-09-24 07:49:23189 EXPECT_CALL(*send_algorithm_,
[email protected]ef0da582014-05-09 07:16:30190 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
[email protected]48878092013-07-26 14:51:56191 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05192 Return(QuicTime::Delta::Zero()));
[email protected]08da9adb2014-04-24 08:33:31193 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
194 Return(kMaxPacketSize));
[email protected]77b5d50b2014-05-07 22:48:48195 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05196 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45197 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05198 Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40199 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44200 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
201 &random_generator_));
[email protected]6d515822014-08-22 01:58:06202 TestPacketWriterFactory writer_factory(socket);
[email protected]3aa9ca72014-02-27 19:39:43203 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
204 connection_id_, peer_addr_,
[email protected]6d515822014-08-22 01:58:06205 helper_.get(), writer_factory);
[email protected]f702d572012-12-04 15:56:20206 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41207 connection_->SetSendAlgorithm(send_algorithm_);
rtenneti041b2992015-02-23 23:03:28208 session_.reset(new QuicClientSession(
209 connection_, scoped_ptr<DatagramClientSocket>(socket), nullptr,
210 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
rtennetif4f08852015-02-27 17:50:04211 DefaultQuicConfig(), "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
rtenneti041b2992015-02-23 23:03:28212 base::MessageLoop::current()->message_loop_proxy().get(), nullptr));
rtennetib998b322014-08-26 00:36:33213 session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
rtenneti4a5df262014-11-07 00:43:58214 /*is_secure=*/false,
215 PRIVACY_MODE_DISABLED),
rtennetib998b322014-08-26 00:36:33216 &crypto_config_,
217 &crypto_client_stream_factory_);
[email protected]ed3fc15d2013-03-08 18:37:44218 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48219 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
[email protected]6cca996b2013-01-25 07:43:36220 stream_.reset(use_closing_stream_ ?
[email protected]0b2294d32013-08-02 00:46:36221 new AutoClosingStream(session_->GetWeakPtr()) :
222 new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36223 }
224
[email protected]1e960032013-12-20 19:00:20225 void SetRequest(const std::string& method,
226 const std::string& path,
227 RequestPriority priority) {
228 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36229 }
230
[email protected]1e960032013-12-20 19:00:20231 void SetResponse(const std::string& status, const std::string& body) {
232 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03233 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36234 }
[email protected]f702d572012-12-04 15:56:20235
[email protected]1e960032013-12-20 19:00:20236 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
[email protected]f702d572012-12-04 15:56:20237 QuicPacketSequenceNumber sequence_number,
[email protected]e8ff26842013-03-22 21:02:05238 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20239 bool fin,
240 QuicStreamOffset offset,
241 base::StringPiece data) {
rtennetif4bdb542015-01-21 14:33:05242 return maker_.MakeDataPacket(sequence_number, stream_id_,
243 should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20244 }
245
[email protected]1e960032013-12-20 19:00:20246 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
247 QuicPacketSequenceNumber sequence_number,
rtennetif4bdb542015-01-21 14:33:05248 bool fin,
249 RequestPriority request_priority) {
250 QuicPriority priority =
251 ConvertRequestPriorityToQuicPriority(request_priority);
252 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
253 kIncludeVersion, fin, priority,
254 request_headers_);
[email protected]1e960032013-12-20 19:00:20255 }
256
257 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
258 QuicPacketSequenceNumber sequence_number,
259 bool fin) {
260 return maker_.MakeResponseHeadersPacket(
261 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
262 }
263
264 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
[email protected]06ff5152013-08-29 01:03:05265 QuicPacketSequenceNumber sequence_number) {
[email protected]1e960032013-12-20 19:00:20266 return maker_.MakeRstPacket(
[email protected]51cc1342014-04-18 23:44:37267 sequence_number, true, stream_id_,
rtenneti4a5df262014-11-07 00:43:58268 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
[email protected]06ff5152013-08-29 01:03:05269 }
270
[email protected]c5e1aca2014-01-30 04:03:04271 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
272 QuicPacketSequenceNumber sequence_number) {
273 return maker_.MakeAckAndRstPacket(
274 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
[email protected]08da9adb2014-04-24 08:33:31275 2, 1, !kIncludeCongestionFeedback);
[email protected]c5e1aca2014-01-30 04:03:04276 }
277
[email protected]1e960032013-12-20 19:00:20278 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
[email protected]f702d572012-12-04 15:56:20279 QuicPacketSequenceNumber sequence_number,
[email protected]63534512012-12-23 18:49:00280 QuicPacketSequenceNumber largest_received,
281 QuicPacketSequenceNumber least_unacked) {
[email protected]1e960032013-12-20 19:00:20282 return maker_.MakeAckPacket(sequence_number, largest_received,
283 least_unacked, !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00284 }
285
[email protected]f702d572012-12-04 15:56:20286 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00287 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41288 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20289 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17290 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20291 MockClock clock_;
292 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44293 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20294 testing::StrictMock<MockConnectionVisitor> visitor_;
295 scoped_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15296 TransportSecurityState transport_security_state_;
[email protected]f702d572012-12-04 15:56:20297 scoped_ptr<QuicClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01298 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20299 TestCompletionCallback callback_;
300 HttpRequestInfo request_;
301 HttpRequestHeaders headers_;
302 HttpResponseInfo response_;
303 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20304 SpdyHeaderBlock request_headers_;
305 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36306 std::string request_data_;
307 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20308
309 private:
[email protected]3aa9ca72014-02-27 19:39:43310 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20311 const QuicStreamId stream_id_;
312 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20313 IPEndPoint self_addr_;
314 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58315 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05316 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20317 scoped_ptr<StaticSocketDataProvider> socket_data_;
318 std::vector<PacketToWrite> writes_;
319};
320
[email protected]1e960032013-12-20 19:00:20321INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
322 ::testing::ValuesIn(QuicSupportedVersions()));
323
324TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44325 Initialize();
rtennetibe635732014-10-02 22:51:42326 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20327}
328
[email protected]1e960032013-12-20 19:00:20329TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
[email protected]ed3fc15d2013-03-08 18:37:44330 Initialize();
[email protected]f702d572012-12-04 15:56:20331 EXPECT_TRUE(stream_->CanFindEndOfResponse());
332}
333
[email protected]1e960032013-12-20 19:00:20334TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
[email protected]ed3fc15d2013-03-08 18:37:44335 Initialize();
[email protected]f702d572012-12-04 15:56:20336 EXPECT_FALSE(stream_->IsConnectionReusable());
337}
338
[email protected]1e960032013-12-20 19:00:20339TEST_P(QuicHttpStreamTest, GetRequest) {
340 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05341 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]f702d572012-12-04 15:56:20342 Initialize();
343
344 request_.method = "GET";
345 request_.url = GURL("http://www.google.com/");
346
[email protected]262eec82013-03-19 21:01:36347 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
348 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20349 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
350 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20351
352 // Ack the request.
[email protected]1e960032013-12-20 19:00:20353 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20354
355 EXPECT_EQ(ERR_IO_PENDING,
356 stream_->ReadResponseHeaders(callback_.callback()));
357
[email protected]1e960032013-12-20 19:00:20358 SetResponse("404 Not Found", std::string());
[email protected]92bf17c2014-03-03 21:14:03359 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]f702d572012-12-04 15:56:20360
361 // Now that the headers have been processed, the callback will return.
362 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36363 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20364 EXPECT_EQ(404, response_.headers->response_code());
365 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53366 EXPECT_FALSE(response_.response_time.is_null());
367 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20368
369 // There is no body, so this should return immediately.
370 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
371 read_buffer_->size(),
372 callback_.callback()));
373 EXPECT_TRUE(stream_->IsResponseBodyComplete());
374 EXPECT_TRUE(AtEof());
375}
376
[email protected]3e7dca62013-09-10 16:14:23377// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20378TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
379 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05380 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]3e7dca62013-09-10 16:14:23381 Initialize();
382
383 request_.method = "GET";
384 request_.url = GURL("http://www.google.com/");
385
386 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
387 net_log_, callback_.callback()));
388 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
389 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23390
391 // Ack the request.
[email protected]1e960032013-12-20 19:00:20392 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23393
394 EXPECT_EQ(ERR_IO_PENDING,
395 stream_->ReadResponseHeaders(callback_.callback()));
396
397 SpdyHeaderBlock headers;
398 headers[":status"] = "200 OK";
399 headers[":version"] = "HTTP/1.1";
400 headers["content-type"] = "text/plain";
401 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
402
403 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
404 EXPECT_LT(4096u, response.length());
405 stream_->OnDataReceived(response.data(), response.length());
406 stream_->OnClose(QUIC_NO_ERROR);
407
408 // Now that the headers have been processed, the callback will return.
409 EXPECT_EQ(OK, callback_.WaitForResult());
410 ASSERT_TRUE(response_.headers.get());
411 EXPECT_EQ(200, response_.headers->response_code());
412 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
413
414 // There is no body, so this should return immediately.
415 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
416 read_buffer_->size(),
417 callback_.callback()));
418 EXPECT_TRUE(stream_->IsResponseBodyComplete());
419 EXPECT_TRUE(AtEof());
420}
421
rchf9f103cbc2014-08-30 05:28:04422// Regression test for http://crbug.com/409101
423TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
424 SetRequest("GET", "/", DEFAULT_PRIORITY);
425 Initialize();
426
427 request_.method = "GET";
428 request_.url = GURL("http://www.google.com/");
429
430 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
431 net_log_, callback_.callback()));
432
433 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
434
435 EXPECT_EQ(ERR_CONNECTION_CLOSED,
436 stream_->SendRequest(headers_, &response_,
437 callback_.callback()));
438}
439
rch11a114a2014-09-04 23:41:59440// Regression test for http://crbug.com/409871
441TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
442 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05443 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
rch11a114a2014-09-04 23:41:59444 Initialize();
445
446 request_.method = "GET";
447 request_.url = GURL("http://www.google.com/");
448
449 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
450 net_log_, callback_.callback()));
451
452 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
453 callback_.callback()));
454
455 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
456
457 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
458}
459
[email protected]1e960032013-12-20 19:00:20460TEST_P(QuicHttpStreamTest, SendPostRequest) {
461 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05462 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03463 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20464 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20465
466 Initialize();
467
[email protected]b2d26cfd2012-12-11 10:36:06468 ScopedVector<UploadElementReader> element_readers;
469 element_readers.push_back(
470 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
mmenkecbc2b712014-10-09 20:29:07471 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20472 request_.method = "POST";
473 request_.url = GURL("http://www.google.com/");
474 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24475 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20476
[email protected]262eec82013-03-19 21:01:36477 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
478 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20479 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
480 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20481
482 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20483 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20484
485 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20486 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03487 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]f702d572012-12-04 15:56:20488
489 // Since the headers have already arrived, this should return immediately.
490 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36491 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20492 EXPECT_EQ(200, response_.headers->response_code());
493 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
494
495 // Send the response body.
496 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03497 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20498 // Since the body has already arrived, this should return immediately.
499 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
500 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
501 callback_.callback()));
502
503 EXPECT_TRUE(stream_->IsResponseBodyComplete());
504 EXPECT_TRUE(AtEof());
505}
506
[email protected]1e960032013-12-20 19:00:20507TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
508 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47509 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05510 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03511 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
512 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
513 kUploadData));
[email protected]1e960032013-12-20 19:00:20514 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47515 Initialize();
516
mmenkecbc2b712014-10-09 20:29:07517 ChunkedUploadDataStream upload_data_stream(0);
518 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:47519
520 request_.method = "POST";
521 request_.url = GURL("http://www.google.com/");
522 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07523 ASSERT_EQ(OK, request_.upload_data_stream->Init(
524 TestCompletionCallback().callback()));
[email protected]c9e49a02013-02-26 05:56:47525
[email protected]262eec82013-03-19 21:01:36526 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
527 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47528 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
529 callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47530
mmenkecbc2b712014-10-09 20:29:07531 upload_data_stream.AppendData(kUploadData, chunk_size, true);
[email protected]c9e49a02013-02-26 05:56:47532
533 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20534 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47535
536 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20537 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03538 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]c9e49a02013-02-26 05:56:47539
540 // Since the headers have already arrived, this should return immediately.
541 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36542 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47543 EXPECT_EQ(200, response_.headers->response_code());
544 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
545
546 // Send the response body.
547 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20548 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
549 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47550
551 // Since the body has already arrived, this should return immediately.
552 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
553 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
554 callback_.callback()));
555
556 EXPECT_TRUE(stream_->IsResponseBodyComplete());
557 EXPECT_TRUE(AtEof());
558}
559
[email protected]16ba7742014-08-22 00:57:25560TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
561 SetRequest("POST", "/", DEFAULT_PRIORITY);
562 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05563 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25564 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
565 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
566 AddWrite(ConstructAckPacket(4, 3, 1));
567 Initialize();
568
mmenkecbc2b712014-10-09 20:29:07569 ChunkedUploadDataStream upload_data_stream(0);
570 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:25571
572 request_.method = "POST";
573 request_.url = GURL("http://www.google.com/");
574 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07575 ASSERT_EQ(OK, request_.upload_data_stream->Init(
576 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25577
578 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
579 net_log_, callback_.callback()));
580 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
581 callback_.callback()));
582
mmenkecbc2b712014-10-09 20:29:07583 upload_data_stream.AppendData(nullptr, 0, true);
[email protected]16ba7742014-08-22 00:57:25584
585 ProcessPacket(ConstructAckPacket(1, 0, 0));
586
587 // Send the response headers (but not the body).
588 SetResponse("200 OK", std::string());
589 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
590
591 // Since the headers have already arrived, this should return immediately.
592 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
593 ASSERT_TRUE(response_.headers.get());
594 EXPECT_EQ(200, response_.headers->response_code());
595 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
596
597 // Send the response body.
598 const char kResponseBody[] = "Hello world!";
599 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
600 kResponseBody));
601
602 // Since the body has already arrived, this should return immediately.
603 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
604 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
605 callback_.callback()));
606
607 EXPECT_TRUE(stream_->IsResponseBodyComplete());
608 EXPECT_TRUE(AtEof());
609}
610
611TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
612 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05613 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25614 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
615 AddWrite(ConstructAckPacket(3, 3, 1));
616 Initialize();
617
mmenkecbc2b712014-10-09 20:29:07618 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:25619
620 request_.method = "POST";
621 request_.url = GURL("http://www.google.com/");
622 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07623 ASSERT_EQ(OK, request_.upload_data_stream->Init(
624 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25625
626 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
627 net_log_, callback_.callback()));
628 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
629 callback_.callback()));
630
mmenkecbc2b712014-10-09 20:29:07631 upload_data_stream.AppendData(nullptr, 0, true);
[email protected]16ba7742014-08-22 00:57:25632
633 ProcessPacket(ConstructAckPacket(1, 0, 0));
634
635 // Send the response headers (but not the body).
636 SetResponse("200 OK", std::string());
637 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
638
639 // Since the headers have already arrived, this should return immediately.
640 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
641 ASSERT_TRUE(response_.headers.get());
642 EXPECT_EQ(200, response_.headers->response_code());
643 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
644
645 // Send the response body.
646 const char kResponseBody[] = "Hello world!";
647 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
648 kResponseBody));
649
650 // Since the body has already arrived, this should return immediately.
651 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
652 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
653 callback_.callback()));
654
655 EXPECT_TRUE(stream_->IsResponseBodyComplete());
656 EXPECT_TRUE(AtEof());
657}
658
[email protected]1e960032013-12-20 19:00:20659TEST_P(QuicHttpStreamTest, DestroyedEarly) {
660 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05661 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]c5e1aca2014-01-30 04:03:04662 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00663 use_closing_stream_ = true;
664 Initialize();
665
666 request_.method = "GET";
667 request_.url = GURL("http://www.google.com/");
668
[email protected]262eec82013-03-19 21:01:36669 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
670 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00671 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58672 callback_.callback()));
[email protected]63534512012-12-23 18:49:00673
674 // Ack the request.
[email protected]1e960032013-12-20 19:00:20675 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00676 EXPECT_EQ(ERR_IO_PENDING,
677 stream_->ReadResponseHeaders(callback_.callback()));
678
679 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20680 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00681 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03682 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]63534512012-12-23 18:49:00683
684 EXPECT_TRUE(AtEof());
685}
686
[email protected]1e960032013-12-20 19:00:20687TEST_P(QuicHttpStreamTest, Priority) {
688 SetRequest("GET", "/", MEDIUM);
rtennetif4bdb542015-01-21 14:33:05689 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
[email protected]c5e1aca2014-01-30 04:03:04690 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58691 use_closing_stream_ = true;
692 Initialize();
693
694 request_.method = "GET";
695 request_.url = GURL("http://www.google.com/");
696
697 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
698 net_log_, callback_.callback()));
699
700 // Check that priority is highest.
701 QuicReliableClientStream* reliable_stream =
702 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
703 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14704 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58705 reliable_stream->EffectivePriority());
706
707 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
708 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58709
710 // Check that priority has now dropped back to MEDIUM.
711 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
712 reliable_stream->EffectivePriority()));
713
714 // Ack the request.
[email protected]1e960032013-12-20 19:00:20715 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58716 EXPECT_EQ(ERR_IO_PENDING,
717 stream_->ReadResponseHeaders(callback_.callback()));
718
719 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20720 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58721 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03722 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]24e5bc52013-09-18 15:36:58723
724 EXPECT_TRUE(AtEof());
725}
726
[email protected]e1cca9a2013-09-20 17:14:44727// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20728TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
729 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44730 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52731
[email protected]08da9adb2014-04-24 08:33:31732 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52733
[email protected]e1cca9a2013-09-20 17:14:44734 Initialize();
735
736 request_.method = "GET";
737 request_.url = GURL("http://www.google.com/");
738
739 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
740 net_log_, callback_.callback()));
741
742 // Check that priority is highest.
743 QuicReliableClientStream* reliable_stream =
744 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
745 DCHECK(reliable_stream);
746 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
747 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14748 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44749 reliable_stream->EffectivePriority());
750
rtennetibe635732014-10-02 22:51:42751 // Set Delegate to nullptr and make sure EffectivePriority returns highest
[email protected]e1cca9a2013-09-20 17:14:44752 // priority.
rtennetibe635732014-10-02 22:51:42753 reliable_stream->SetDelegate(nullptr);
[email protected]9f0dcd4e2014-01-16 15:58:14754 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44755 reliable_stream->EffectivePriority());
756 reliable_stream->SetDelegate(delegate);
757}
758
[email protected]f702d572012-12-04 15:56:20759} // namespace test
[email protected]f702d572012-12-04 15:56:20760} // namespace net