blob: ed42db6ecc3918ace57eb1e782cadb09ac88f239 [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!";
bncb07c05532015-05-14 19:07:2053const char kDefaultServerHostName[] = "www.google.com";
54const uint16 kDefaultServerPort = 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),
bncb07c05532015-05-14 19:07:20138 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
[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() {
rch37de576c2015-05-17 20:28:17165 return socket_data_->AllReadDataConsumed() &&
166 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20167 }
168
[email protected]1e960032013-12-20 19:00:20169 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
170 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20171 }
172
173 // Configures the test fixture to use the list of expected writes.
174 void Initialize() {
175 mock_writes_.reset(new MockWrite[writes_.size()]);
176 for (size_t i = 0; i < writes_.size(); i++) {
177 mock_writes_[i] = MockWrite(writes_[i].mode,
178 writes_[i].packet->data(),
179 writes_[i].packet->length());
180 };
181
rtennetibe635732014-10-02 22:51:42182 socket_data_.reset(new StaticSocketDataProvider(
183 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20184
[email protected]e13201d82012-12-12 05:00:32185 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
186 net_log_.net_log());
187 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20188 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41189 send_algorithm_ = new MockSendAlgorithm();
[email protected]efecff92013-09-24 07:49:23190 EXPECT_CALL(*send_algorithm_,
[email protected]ef0da582014-05-09 07:16:30191 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
[email protected]48878092013-07-26 14:51:56192 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05193 Return(QuicTime::Delta::Zero()));
[email protected]08da9adb2014-04-24 08:33:31194 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
195 Return(kMaxPacketSize));
[email protected]77b5d50b2014-05-07 22:48:48196 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
[email protected]06ff5152013-08-29 01:03:05197 WillRepeatedly(Return(QuicTime::Delta::Zero()));
[email protected]ea825e02013-08-21 18:12:45198 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
[email protected]06ff5152013-08-29 01:03:05199 Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40200 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
[email protected]2cfc6bb82013-10-27 03:40:44201 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
202 &random_generator_));
[email protected]6d515822014-08-22 01:58:06203 TestPacketWriterFactory writer_factory(socket);
[email protected]3aa9ca72014-02-27 19:39:43204 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
205 connection_id_, peer_addr_,
[email protected]6d515822014-08-22 01:58:06206 helper_.get(), writer_factory);
[email protected]f702d572012-12-04 15:56:20207 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41208 connection_->SetSendAlgorithm(send_algorithm_);
rtenneti041b2992015-02-23 23:03:28209 session_.reset(new QuicClientSession(
210 connection_, scoped_ptr<DatagramClientSocket>(socket), nullptr,
211 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
rtennetif4f08852015-02-27 17:50:04212 DefaultQuicConfig(), "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
rtenneti041b2992015-02-23 23:03:28213 base::MessageLoop::current()->message_loop_proxy().get(), nullptr));
bncb07c05532015-05-14 19:07:20214 session_->InitializeSession(
215 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
216 /*is_secure=*/false, PRIVACY_MODE_DISABLED),
217 &crypto_config_, &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
rchc0815442015-04-18 13:29:46403 std::string response =
404 SpdyUtils::SerializeUncompressedHeaders(headers, GetParam());
[email protected]3e7dca62013-09-10 16:14:23405 EXPECT_LT(4096u, response.length());
406 stream_->OnDataReceived(response.data(), response.length());
407 stream_->OnClose(QUIC_NO_ERROR);
408
409 // Now that the headers have been processed, the callback will return.
410 EXPECT_EQ(OK, callback_.WaitForResult());
411 ASSERT_TRUE(response_.headers.get());
412 EXPECT_EQ(200, response_.headers->response_code());
413 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
414
415 // There is no body, so this should return immediately.
416 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
417 read_buffer_->size(),
418 callback_.callback()));
419 EXPECT_TRUE(stream_->IsResponseBodyComplete());
420 EXPECT_TRUE(AtEof());
421}
422
rchf9f103cbc2014-08-30 05:28:04423// Regression test for http://crbug.com/409101
424TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
425 SetRequest("GET", "/", DEFAULT_PRIORITY);
426 Initialize();
427
428 request_.method = "GET";
429 request_.url = GURL("http://www.google.com/");
430
431 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
432 net_log_, callback_.callback()));
433
434 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
435
436 EXPECT_EQ(ERR_CONNECTION_CLOSED,
437 stream_->SendRequest(headers_, &response_,
438 callback_.callback()));
439}
440
rch11a114a2014-09-04 23:41:59441// Regression test for http://crbug.com/409871
442TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
443 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05444 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
rch11a114a2014-09-04 23:41:59445 Initialize();
446
447 request_.method = "GET";
448 request_.url = GURL("http://www.google.com/");
449
450 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
451 net_log_, callback_.callback()));
452
453 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
454 callback_.callback()));
455
456 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
457
458 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
459}
460
[email protected]1e960032013-12-20 19:00:20461TEST_P(QuicHttpStreamTest, SendPostRequest) {
462 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05463 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03464 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20465 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20466
467 Initialize();
468
[email protected]b2d26cfd2012-12-11 10:36:06469 ScopedVector<UploadElementReader> element_readers;
470 element_readers.push_back(
471 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
mmenkecbc2b712014-10-09 20:29:07472 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]f702d572012-12-04 15:56:20473 request_.method = "POST";
474 request_.url = GURL("http://www.google.com/");
475 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24476 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20477
[email protected]262eec82013-03-19 21:01:36478 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
479 net_log_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20480 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
481 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20482
483 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20484 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20485
486 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20487 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03488 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]f702d572012-12-04 15:56:20489
490 // Since the headers have already arrived, this should return immediately.
491 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36492 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20493 EXPECT_EQ(200, response_.headers->response_code());
494 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
495
496 // Send the response body.
497 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03498 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20499 // Since the body has already arrived, this should return immediately.
500 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
501 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
502 callback_.callback()));
503
504 EXPECT_TRUE(stream_->IsResponseBodyComplete());
505 EXPECT_TRUE(AtEof());
506}
507
[email protected]1e960032013-12-20 19:00:20508TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
509 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47510 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05511 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]92bf17c2014-03-03 21:14:03512 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
513 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
514 kUploadData));
[email protected]1e960032013-12-20 19:00:20515 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47516 Initialize();
517
mmenkecbc2b712014-10-09 20:29:07518 ChunkedUploadDataStream upload_data_stream(0);
519 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:47520
521 request_.method = "POST";
522 request_.url = GURL("http://www.google.com/");
523 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07524 ASSERT_EQ(OK, request_.upload_data_stream->Init(
525 TestCompletionCallback().callback()));
[email protected]c9e49a02013-02-26 05:56:47526
[email protected]262eec82013-03-19 21:01:36527 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
528 net_log_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47529 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
530 callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47531
mmenkecbc2b712014-10-09 20:29:07532 upload_data_stream.AppendData(kUploadData, chunk_size, true);
[email protected]c9e49a02013-02-26 05:56:47533
534 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20535 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47536
537 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20538 SetResponse("200 OK", std::string());
[email protected]92bf17c2014-03-03 21:14:03539 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
[email protected]c9e49a02013-02-26 05:56:47540
541 // Since the headers have already arrived, this should return immediately.
542 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]cadac622013-06-11 16:46:36543 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47544 EXPECT_EQ(200, response_.headers->response_code());
545 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
546
547 // Send the response body.
548 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20549 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
550 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47551
552 // Since the body has already arrived, this should return immediately.
553 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
554 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
555 callback_.callback()));
556
557 EXPECT_TRUE(stream_->IsResponseBodyComplete());
558 EXPECT_TRUE(AtEof());
559}
560
[email protected]16ba7742014-08-22 00:57:25561TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
562 SetRequest("POST", "/", DEFAULT_PRIORITY);
563 size_t chunk_size = strlen(kUploadData);
rtennetif4bdb542015-01-21 14:33:05564 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25565 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
566 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
567 AddWrite(ConstructAckPacket(4, 3, 1));
568 Initialize();
569
mmenkecbc2b712014-10-09 20:29:07570 ChunkedUploadDataStream upload_data_stream(0);
571 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:25572
573 request_.method = "POST";
574 request_.url = GURL("http://www.google.com/");
575 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07576 ASSERT_EQ(OK, request_.upload_data_stream->Init(
577 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25578
579 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
580 net_log_, callback_.callback()));
581 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
582 callback_.callback()));
583
mmenkecbc2b712014-10-09 20:29:07584 upload_data_stream.AppendData(nullptr, 0, true);
[email protected]16ba7742014-08-22 00:57:25585
586 ProcessPacket(ConstructAckPacket(1, 0, 0));
587
588 // Send the response headers (but not the body).
589 SetResponse("200 OK", std::string());
590 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
591
592 // Since the headers have already arrived, this should return immediately.
593 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
594 ASSERT_TRUE(response_.headers.get());
595 EXPECT_EQ(200, response_.headers->response_code());
596 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
597
598 // Send the response body.
599 const char kResponseBody[] = "Hello world!";
600 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
601 kResponseBody));
602
603 // Since the body has already arrived, this should return immediately.
604 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
605 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
606 callback_.callback()));
607
608 EXPECT_TRUE(stream_->IsResponseBodyComplete());
609 EXPECT_TRUE(AtEof());
610}
611
612TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
613 SetRequest("POST", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05614 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
[email protected]16ba7742014-08-22 00:57:25615 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
616 AddWrite(ConstructAckPacket(3, 3, 1));
617 Initialize();
618
mmenkecbc2b712014-10-09 20:29:07619 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:25620
621 request_.method = "POST";
622 request_.url = GURL("http://www.google.com/");
623 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07624 ASSERT_EQ(OK, request_.upload_data_stream->Init(
625 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25626
627 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
628 net_log_, callback_.callback()));
629 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
630 callback_.callback()));
631
mmenkecbc2b712014-10-09 20:29:07632 upload_data_stream.AppendData(nullptr, 0, true);
[email protected]16ba7742014-08-22 00:57:25633
634 ProcessPacket(ConstructAckPacket(1, 0, 0));
635
636 // Send the response headers (but not the body).
637 SetResponse("200 OK", std::string());
638 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
639
640 // Since the headers have already arrived, this should return immediately.
641 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
642 ASSERT_TRUE(response_.headers.get());
643 EXPECT_EQ(200, response_.headers->response_code());
644 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
645
646 // Send the response body.
647 const char kResponseBody[] = "Hello world!";
648 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
649 kResponseBody));
650
651 // Since the body has already arrived, this should return immediately.
652 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
653 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
654 callback_.callback()));
655
656 EXPECT_TRUE(stream_->IsResponseBodyComplete());
657 EXPECT_TRUE(AtEof());
658}
659
[email protected]1e960032013-12-20 19:00:20660TEST_P(QuicHttpStreamTest, DestroyedEarly) {
661 SetRequest("GET", "/", DEFAULT_PRIORITY);
rtennetif4bdb542015-01-21 14:33:05662 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
[email protected]c5e1aca2014-01-30 04:03:04663 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00664 use_closing_stream_ = true;
665 Initialize();
666
667 request_.method = "GET";
668 request_.url = GURL("http://www.google.com/");
669
[email protected]262eec82013-03-19 21:01:36670 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
671 net_log_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00672 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
[email protected]24e5bc52013-09-18 15:36:58673 callback_.callback()));
[email protected]63534512012-12-23 18:49:00674
675 // Ack the request.
[email protected]1e960032013-12-20 19:00:20676 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]63534512012-12-23 18:49:00677 EXPECT_EQ(ERR_IO_PENDING,
678 stream_->ReadResponseHeaders(callback_.callback()));
679
680 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20681 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00682 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03683 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]63534512012-12-23 18:49:00684
685 EXPECT_TRUE(AtEof());
686}
687
[email protected]1e960032013-12-20 19:00:20688TEST_P(QuicHttpStreamTest, Priority) {
689 SetRequest("GET", "/", MEDIUM);
rtennetif4bdb542015-01-21 14:33:05690 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
[email protected]c5e1aca2014-01-30 04:03:04691 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58692 use_closing_stream_ = true;
693 Initialize();
694
695 request_.method = "GET";
696 request_.url = GURL("http://www.google.com/");
697
698 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
699 net_log_, callback_.callback()));
700
701 // Check that priority is highest.
702 QuicReliableClientStream* reliable_stream =
703 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
704 DCHECK(reliable_stream);
[email protected]9f0dcd4e2014-01-16 15:58:14705 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]24e5bc52013-09-18 15:36:58706 reliable_stream->EffectivePriority());
707
708 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
709 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58710
711 // Check that priority has now dropped back to MEDIUM.
712 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
713 reliable_stream->EffectivePriority()));
714
715 // Ack the request.
[email protected]1e960032013-12-20 19:00:20716 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]24e5bc52013-09-18 15:36:58717 EXPECT_EQ(ERR_IO_PENDING,
718 stream_->ReadResponseHeaders(callback_.callback()));
719
720 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20721 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58722 // In the course of processing this packet, the QuicHttpStream close itself.
[email protected]92bf17c2014-03-03 21:14:03723 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
[email protected]24e5bc52013-09-18 15:36:58724
725 EXPECT_TRUE(AtEof());
726}
727
[email protected]e1cca9a2013-09-20 17:14:44728// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20729TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
730 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44731 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52732
[email protected]08da9adb2014-04-24 08:33:31733 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52734
[email protected]e1cca9a2013-09-20 17:14:44735 Initialize();
736
737 request_.method = "GET";
738 request_.url = GURL("http://www.google.com/");
739
740 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
741 net_log_, callback_.callback()));
742
743 // Check that priority is highest.
744 QuicReliableClientStream* reliable_stream =
745 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
746 DCHECK(reliable_stream);
747 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
748 DCHECK(delegate);
[email protected]9f0dcd4e2014-01-16 15:58:14749 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44750 reliable_stream->EffectivePriority());
751
rtennetibe635732014-10-02 22:51:42752 // Set Delegate to nullptr and make sure EffectivePriority returns highest
[email protected]e1cca9a2013-09-20 17:14:44753 // priority.
rtennetibe635732014-10-02 22:51:42754 reliable_stream->SetDelegate(nullptr);
[email protected]9f0dcd4e2014-01-16 15:58:14755 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
[email protected]e1cca9a2013-09-20 17:14:44756 reliable_stream->EffectivePriority());
757 reliable_stream->SetDelegate(delegate);
758}
759
[email protected]f702d572012-12-04 15:56:20760} // namespace test
[email protected]f702d572012-12-04 15:56:20761} // namespace net