blob: e514c03883c2051795e1e65b8eb1cc0fc8ee2f5d [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
sclittle1edeeb22015-09-02 20:46:107#include <stdint.h>
8
[email protected]f702d572012-12-04 15:56:209#include <vector>
10
olli.raula6df48b2a2015-11-26 07:40:2211#include "base/memory/scoped_ptr.h"
skyostil4891b25b2015-06-11 11:43:4512#include "base/thread_task_runner_handle.h"
mmenkecbc2b712014-10-09 20:29:0713#include "net/base/chunked_upload_data_stream.h"
14#include "net/base/elements_upload_data_stream.h"
[email protected]f702d572012-12-04 15:56:2015#include "net/base/net_errors.h"
tbansalfdf5665b2015-09-21 22:46:4016#include "net/base/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2017#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0618#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2019#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1520#include "net/http/transport_security_state.h"
[email protected]fee17f72013-02-03 07:47:4121#include "net/quic/congestion_control/send_algorithm_interface.h"
[email protected]e8ff26842013-03-22 21:02:0522#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1623#include "net/quic/crypto/quic_decrypter.h"
24#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0425#include "net/quic/crypto/quic_server_info.h"
ckrasic4f9d88d2015-07-22 22:23:1626#include "net/quic/quic_chromium_client_session.h"
[email protected]f702d572012-12-04 15:56:2027#include "net/quic/quic_connection.h"
28#include "net/quic/quic_connection_helper.h"
[email protected]cbd731e2013-10-24 00:20:3929#include "net/quic/quic_default_packet_writer.h"
[email protected]24e5bc52013-09-18 15:36:5830#include "net/quic/quic_http_utils.h"
rtenneti1cd3b162015-09-29 02:58:2831#include "net/quic/quic_packet_reader.h"
[email protected]24e5bc52013-09-18 15:36:5832#include "net/quic/quic_reliable_client_stream.h"
[email protected]9f0dcd4e2014-01-16 15:58:1433#include "net/quic/quic_write_blocked_list.h"
[email protected]3e7dca62013-09-10 16:14:2334#include "net/quic/spdy_utils.h"
rch1fe2eeb2015-10-26 14:45:5735#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]f702d572012-12-04 15:56:2036#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0537#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0338#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3939#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2040#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2041#include "net/quic/test_tools/quic_test_utils.h"
42#include "net/quic/test_tools/test_task_runner.h"
43#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3644#include "net/spdy/spdy_frame_builder.h"
45#include "net/spdy/spdy_framer.h"
46#include "net/spdy/spdy_http_utils.h"
47#include "net/spdy/spdy_protocol.h"
[email protected]f702d572012-12-04 15:56:2048#include "testing/gmock/include/gmock/gmock.h"
49#include "testing/gtest/include/gtest/gtest.h"
50
51using testing::_;
[email protected]06ff5152013-08-29 01:03:0552using testing::AnyNumber;
53using testing::Return;
[email protected]f702d572012-12-04 15:56:2054
55namespace net {
[email protected]f702d572012-12-04 15:56:2056namespace test {
[email protected]f702d572012-12-04 15:56:2057namespace {
58
[email protected]16ba7742014-08-22 00:57:2559const char kUploadData[] = "Really nifty data!";
bncb07c05532015-05-14 19:07:2060const char kDefaultServerHostName[] = "www.google.com";
Avi Drissman13fc8932015-12-20 04:40:4661const uint16_t kDefaultServerPort = 80;
[email protected]f702d572012-12-04 15:56:2062
63class TestQuicConnection : public QuicConnection {
64 public:
[email protected]1e960032013-12-20 19:00:2065 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4366 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2067 IPEndPoint address,
[email protected]cbd731e2013-10-24 00:20:3968 QuicConnectionHelper* helper,
jdorfman90d185f32016-01-15 13:22:4769 QuicPacketWriter* writer)
[email protected]66cd2d62014-08-01 18:42:3970 : QuicConnection(connection_id,
71 address,
72 helper,
jdorfman90d185f32016-01-15 13:22:4773 writer,
rtenneti6f48aa92015-03-16 02:18:4874 true /* owns_writer */,
75 Perspective::IS_CLIENT,
rtenneti6f48aa92015-03-16 02:18:4876 versions) {}
[email protected]f702d572012-12-04 15:56:2077
[email protected]fee17f72013-02-03 07:47:4178 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
79 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
[email protected]f702d572012-12-04 15:56:2080 }
81};
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:
ckrasic4f9d88d2015-07-22 22:23:1687 explicit AutoClosingStream(
88 const base::WeakPtr<QuicChromiumClientSession>& session)
89 : QuicHttpStream(session) {}
[email protected]63534512012-12-23 18:49:0090
sclittlec4dc1a32015-09-24 00:15:4591 void OnHeadersAvailable(const SpdyHeaderBlock& headers,
92 size_t frame_len) override {
[email protected]63534512012-12-23 18:49:0093 Close(false);
[email protected]63534512012-12-23 18:49:0094 }
rchb27683c2015-07-29 23:53:5095
96 void OnDataAvailable() override { Close(false); }
[email protected]63534512012-12-23 18:49:0097};
98
[email protected]f702d572012-12-04 15:56:2099} // namespace
100
[email protected]24e5bc52013-09-18 15:36:58101class QuicHttpStreamPeer {
102 public:
103 static QuicReliableClientStream* GetQuicReliableClientStream(
104 QuicHttpStream* stream) {
105 return stream->stream_;
106 }
zhongyica364fbb2015-12-12 03:39:12107
108 static bool WasHandshakeConfirmed(QuicHttpStream* stream) {
109 return stream->was_handshake_confirmed_;
110 }
111
112 static void SetHandshakeConfirmed(QuicHttpStream* stream, bool confirmed) {
113 stream->was_handshake_confirmed_ = confirmed;
114 }
[email protected]24e5bc52013-09-18 15:36:58115};
116
[email protected]1e960032013-12-20 19:00:20117class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20118 protected:
[email protected]1e960032013-12-20 19:00:20119 static const bool kFin = true;
120 static const bool kIncludeVersion = true;
121 static const bool kIncludeCongestionFeedback = true;
122
[email protected]f702d572012-12-04 15:56:20123 // Holds a packet to be written to the wire, and the IO mode that should
124 // be used by the mock socket when performing the write.
125 struct PacketToWrite {
126 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
rjshaded5ced072015-12-18 19:26:02127 : mode(mode), packet(packet) {}
[email protected]f702d572012-12-04 15:56:20128 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),
rch1fe2eeb2015-10-26 14:45:57135 crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
[email protected]f702d572012-12-04 15:56:20136 read_buffer_(new IOBufferWithSize(4096)),
[email protected]3aa9ca72014-02-27 19:39:43137 connection_id_(2),
[email protected]66ae5962014-05-22 11:13:05138 stream_id_(kClientDataStreamId1),
bncb07c05532015-05-14 19:07:20139 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
[email protected]1e960032013-12-20 19:00:20140 random_generator_(0) {
[email protected]f702d572012-12-04 15:56:20141 IPAddressNumber ip;
142 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
143 peer_addr_ = IPEndPoint(ip, 443);
144 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43145 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20146 }
147
148 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19149 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20150 for (size_t i = 0; i < writes_.size(); i++) {
151 delete writes_[i].packet;
152 }
153 }
154
155 // Adds a packet to the list of expected writes.
[email protected]1e960032013-12-20 19:00:20156 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
157 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20158 }
159
160 // Returns the packet to be written at position |pos|.
rjshaded5ced072015-12-18 19:26:02161 QuicEncryptedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20162
163 bool AtEof() {
rch37de576c2015-05-17 20:28:17164 return socket_data_->AllReadDataConsumed() &&
165 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20166 }
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++) {
rjshaded5ced072015-12-18 19:26:02176 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
[email protected]f702d572012-12-04 15:56:20177 writes_[i].packet->length());
178 };
179
rtennetibe635732014-10-02 22:51:42180 socket_data_.reset(new StaticSocketDataProvider(
181 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20182
rjshaded5ced072015-12-18 19:26:02183 MockUDPClientSocket* socket =
184 new MockUDPClientSocket(socket_data_.get(), net_log_.net_log());
[email protected]e13201d82012-12-12 05:00:32185 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20186 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41187 send_algorithm_ = new MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57188 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
189 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
rjshaded5ced072015-12-18 19:26:02190 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
191 .WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07192 EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
193 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
194 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
195 .WillRepeatedly(Return(kMaxPacketSize));
196 EXPECT_CALL(*send_algorithm_, PacingRate())
197 .WillRepeatedly(Return(QuicBandwidth::Zero()));
198 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _))
199 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
200 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
201 .WillRepeatedly(Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40202 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rjshaded5ced072015-12-18 19:26:02203 helper_.reset(
204 new QuicConnectionHelper(runner_.get(), &clock_, &random_generator_));
jdorfman90d185f32016-01-15 13:22:47205 connection_ = new TestQuicConnection(
206 SupportedVersions(GetParam()), connection_id_, peer_addr_,
207 helper_.get(), new QuicDefaultPacketWriter(socket));
[email protected]f702d572012-12-04 15:56:20208 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41209 connection_->SetSendAlgorithm(send_algorithm_);
ckrasic4f9d88d2015-07-22 22:23:16210 session_.reset(new QuicChromiumClientSession(
rtennetid39bd762015-06-12 01:05:52211 connection_, scoped_ptr<DatagramClientSocket>(socket),
rtenneti1cd3b162015-09-29 02:58:28212 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
rtenneti041b2992015-02-23 23:03:28213 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
bncb07c05532015-05-14 19:07:20214 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
rch1fe2eeb2015-10-26 14:45:57215 PRIVACY_MODE_DISABLED),
rtenneti1cd3b162015-09-29 02:58:28216 kQuicYieldAfterPacketsRead,
217 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
rtennetia75df622015-06-21 23:59:50218 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
219 "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
tbansalfdf5665b2015-09-21 22:46:40220 base::ThreadTaskRunnerHandle::Get().get(),
221 /*socket_performance_watcher=*/nullptr, nullptr));
rtennetid39bd762015-06-12 01:05:52222 session_->Initialize();
[email protected]ed3fc15d2013-03-08 18:37:44223 session_->GetCryptoStream()->CryptoConnect();
[email protected]8ba81212013-05-03 13:11:48224 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
rjshaded5ced072015-12-18 19:26:02225 stream_.reset(use_closing_stream_
226 ? new AutoClosingStream(session_->GetWeakPtr())
227 : new QuicHttpStream(session_->GetWeakPtr()));
[email protected]6cca996b2013-01-25 07:43:36228 }
229
[email protected]1e960032013-12-20 19:00:20230 void SetRequest(const std::string& method,
231 const std::string& path,
232 RequestPriority priority) {
233 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36234 }
235
[email protected]1e960032013-12-20 19:00:20236 void SetResponse(const std::string& status, const std::string& body) {
237 response_headers_ = maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03238 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36239 }
[email protected]f702d572012-12-04 15:56:20240
[email protected]1e960032013-12-20 19:00:20241 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
rtennetia004d332015-08-28 06:44:57242 QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05243 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20244 bool fin,
245 QuicStreamOffset offset,
246 base::StringPiece data) {
rtennetia004d332015-08-28 06:44:57247 return maker_.MakeDataPacket(packet_number, stream_id_,
rtennetif4bdb542015-01-21 14:33:05248 should_include_version, fin, offset, data);
[email protected]f702d572012-12-04 15:56:20249 }
250
[email protected]1e960032013-12-20 19:00:20251 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
rtennetia004d332015-08-28 06:44:57252 QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05253 bool fin,
sclittlec4dc1a32015-09-24 00:15:45254 RequestPriority request_priority,
255 size_t* spdy_headers_frame_length) {
ianswett0888cff2015-11-24 17:42:16256 SpdyPriority priority =
rtennetif4bdb542015-01-21 14:33:05257 ConvertRequestPriorityToQuicPriority(request_priority);
sclittlec4dc1a32015-09-24 00:15:45258 return maker_.MakeRequestHeadersPacket(
259 packet_number, stream_id_, kIncludeVersion, fin, priority,
260 request_headers_, spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20261 }
262
263 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
rtennetia004d332015-08-28 06:44:57264 QuicPacketNumber packet_number,
sclittlec4dc1a32015-09-24 00:15:45265 bool fin,
266 size_t* spdy_headers_frame_length) {
[email protected]1e960032013-12-20 19:00:20267 return maker_.MakeResponseHeadersPacket(
sclittlec4dc1a32015-09-24 00:15:45268 packet_number, stream_id_, !kIncludeVersion, fin, response_headers_,
269 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20270 }
271
272 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
rtennetia004d332015-08-28 06:44:57273 QuicPacketNumber packet_number) {
[email protected]1e960032013-12-20 19:00:20274 return maker_.MakeRstPacket(
rtennetia004d332015-08-28 06:44:57275 packet_number, true, stream_id_,
rtenneti4a5df262014-11-07 00:43:58276 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
[email protected]06ff5152013-08-29 01:03:05277 }
278
rtenneti6bd660b2015-07-18 00:19:53279 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
rtennetia004d332015-08-28 06:44:57280 QuicPacketNumber packet_number) {
281 return maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
rtenneti6bd660b2015-07-18 00:19:53282 QUIC_STREAM_CANCELLED);
283 }
284
[email protected]c5e1aca2014-01-30 04:03:04285 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
rtennetia004d332015-08-28 06:44:57286 QuicPacketNumber packet_number) {
287 return maker_.MakeAckAndRstPacket(packet_number, !kIncludeVersion,
288 stream_id_, QUIC_STREAM_CANCELLED, 2, 1,
289 !kIncludeCongestionFeedback);
[email protected]c5e1aca2014-01-30 04:03:04290 }
291
[email protected]1e960032013-12-20 19:00:20292 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
rtennetia004d332015-08-28 06:44:57293 QuicPacketNumber packet_number,
294 QuicPacketNumber largest_received,
295 QuicPacketNumber least_unacked) {
296 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
297 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00298 }
299
[email protected]f702d572012-12-04 15:56:20300 BoundNetLog net_log_;
[email protected]63534512012-12-23 18:49:00301 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41302 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20303 scoped_refptr<TestTaskRunner> runner_;
[email protected]4356f0f2013-04-07 00:58:17304 scoped_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20305 MockClock clock_;
306 TestQuicConnection* connection_;
[email protected]2cfc6bb82013-10-27 03:40:44307 scoped_ptr<QuicConnectionHelper> helper_;
[email protected]f702d572012-12-04 15:56:20308 testing::StrictMock<MockConnectionVisitor> visitor_;
309 scoped_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15310 TransportSecurityState transport_security_state_;
ckrasic4f9d88d2015-07-22 22:23:16311 scoped_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01312 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20313 TestCompletionCallback callback_;
314 HttpRequestInfo request_;
315 HttpRequestHeaders headers_;
316 HttpResponseInfo response_;
317 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20318 SpdyHeaderBlock request_headers_;
319 SpdyHeaderBlock response_headers_;
[email protected]6cca996b2013-01-25 07:43:36320 std::string request_data_;
321 std::string response_data_;
[email protected]f702d572012-12-04 15:56:20322
323 private:
[email protected]3aa9ca72014-02-27 19:39:43324 const QuicConnectionId connection_id_;
[email protected]1e960032013-12-20 19:00:20325 const QuicStreamId stream_id_;
326 QuicTestPacketMaker maker_;
[email protected]f702d572012-12-04 15:56:20327 IPEndPoint self_addr_;
328 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58329 MockRandom random_generator_;
[email protected]e8ff26842013-03-22 21:02:05330 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]f702d572012-12-04 15:56:20331 scoped_ptr<StaticSocketDataProvider> socket_data_;
332 std::vector<PacketToWrite> writes_;
333};
334
rjshaded5ced072015-12-18 19:26:02335INSTANTIATE_TEST_CASE_P(Version,
336 QuicHttpStreamTest,
[email protected]1e960032013-12-20 19:00:20337 ::testing::ValuesIn(QuicSupportedVersions()));
338
339TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44340 Initialize();
rtennetibe635732014-10-02 22:51:42341 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20342}
343
mmenkebd84c392015-09-02 14:12:34344TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44345 Initialize();
mmenkebd84c392015-09-02 14:12:34346 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20347}
348
[email protected]1e960032013-12-20 19:00:20349TEST_P(QuicHttpStreamTest, GetRequest) {
350 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45351 size_t spdy_request_header_frame_length;
352 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
353 &spdy_request_header_frame_length));
[email protected]f702d572012-12-04 15:56:20354 Initialize();
355
356 request_.method = "GET";
357 request_.url = GURL("http://www.google.com/");
358
rjshaded5ced072015-12-18 19:26:02359 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
360 callback_.callback()));
361 EXPECT_EQ(OK,
362 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20363
364 // Ack the request.
[email protected]1e960032013-12-20 19:00:20365 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20366
rjshaded5ced072015-12-18 19:26:02367 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]f702d572012-12-04 15:56:20368
[email protected]1e960032013-12-20 19:00:20369 SetResponse("404 Not Found", std::string());
sclittlec4dc1a32015-09-24 00:15:45370 size_t spdy_response_header_frame_length;
371 ProcessPacket(ConstructResponseHeadersPacket(
372 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20373
374 // Now that the headers have been processed, the callback will return.
375 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36376 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20377 EXPECT_EQ(404, response_.headers->response_code());
378 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53379 EXPECT_FALSE(response_.response_time.is_null());
380 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20381
382 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02383 EXPECT_EQ(0,
384 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
385 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20386 EXPECT_TRUE(stream_->IsResponseBodyComplete());
387 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10388
389 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45390 // headers and payload.
391 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
392 stream_->GetTotalSentBytes());
393 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
394 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20395}
396
[email protected]3e7dca62013-09-10 16:14:23397// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20398TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
399 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45400 size_t spdy_request_headers_frame_length;
401 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
402 &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23403 Initialize();
404
405 request_.method = "GET";
406 request_.url = GURL("http://www.google.com/");
407
rjshaded5ced072015-12-18 19:26:02408 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
409 callback_.callback()));
410 EXPECT_EQ(OK,
411 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23412
413 // Ack the request.
[email protected]1e960032013-12-20 19:00:20414 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23415
rjshaded5ced072015-12-18 19:26:02416 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23417
418 SpdyHeaderBlock headers;
419 headers[":status"] = "200 OK";
420 headers[":version"] = "HTTP/1.1";
421 headers["content-type"] = "text/plain";
rch7dd15702015-07-01 18:57:57422 headers["big6"] = std::string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23423
rch7dd15702015-07-01 18:57:57424 response_headers_ = headers;
sclittlec4dc1a32015-09-24 00:15:45425 size_t spdy_response_headers_frame_length;
426 ProcessPacket(ConstructResponseHeadersPacket(
427 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23428
429 // Now that the headers have been processed, the callback will return.
430 EXPECT_EQ(OK, callback_.WaitForResult());
431 ASSERT_TRUE(response_.headers.get());
432 EXPECT_EQ(200, response_.headers->response_code());
433 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
434
435 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02436 EXPECT_EQ(0,
437 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
438 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23439 EXPECT_TRUE(stream_->IsResponseBodyComplete());
440 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10441
442 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45443 // headers and payload.
444 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
445 stream_->GetTotalSentBytes());
446 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
447 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:23448}
449
rchf9f103cbc2014-08-30 05:28:04450// Regression test for http://crbug.com/409101
451TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
452 SetRequest("GET", "/", DEFAULT_PRIORITY);
453 Initialize();
454
455 request_.method = "GET";
456 request_.url = GURL("http://www.google.com/");
457
rjshaded5ced072015-12-18 19:26:02458 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
459 callback_.callback()));
rchf9f103cbc2014-08-30 05:28:04460
461 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
462
463 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:02464 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10465
466 EXPECT_EQ(0, stream_->GetTotalSentBytes());
467 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:04468}
469
zhongyica364fbb2015-12-12 03:39:12470TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
471 SetRequest("GET", "/", DEFAULT_PRIORITY);
472 size_t spdy_request_headers_frame_length;
473 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
474 &spdy_request_headers_frame_length));
475 AddWrite(ConstructAckAndRstStreamPacket(2));
476 use_closing_stream_ = true;
477 Initialize();
478
479 request_.method = "GET";
480 request_.url = GURL("http://www.google.com/");
481
482 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
483 callback_.callback()));
484 EXPECT_EQ(OK,
485 stream_->SendRequest(headers_, &response_, callback_.callback()));
486
487 // Ack the request.
488 ProcessPacket(ConstructAckPacket(1, 0, 0));
489 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
490
491 EXPECT_TRUE(QuicHttpStreamPeer::WasHandshakeConfirmed(stream_.get()));
492 stream_->OnClose(QUIC_PEER_GOING_AWAY);
493
494 NetErrorDetails details;
495 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
496 stream_->PopulateNetErrorDetails(&details);
497 EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
498}
499
500TEST_P(QuicHttpStreamTest, DoNotLogGranularQuicErrorIfHandshakeNotConfirmed) {
501 SetRequest("GET", "/", DEFAULT_PRIORITY);
502 size_t spdy_request_headers_frame_length;
503 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
504 &spdy_request_headers_frame_length));
505 AddWrite(ConstructAckAndRstStreamPacket(2));
506 use_closing_stream_ = true;
507 Initialize();
508
509 request_.method = "GET";
510 request_.url = GURL("http://www.google.com/");
511
512 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
513 callback_.callback()));
514 EXPECT_EQ(OK,
515 stream_->SendRequest(headers_, &response_, callback_.callback()));
516
517 // Ack the request.
518 ProcessPacket(ConstructAckPacket(1, 0, 0));
519 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
520
521 // The test setup defaults handshake to be confirmed. Manually set
522 // it to be not confirmed.
523 // Granular errors shouldn't be reported if handshake not confirmed.
524 QuicHttpStreamPeer::SetHandshakeConfirmed(stream_.get(), false);
525
526 EXPECT_FALSE(QuicHttpStreamPeer::WasHandshakeConfirmed(stream_.get()));
527 stream_->OnClose(QUIC_PEER_GOING_AWAY);
528
529 NetErrorDetails details;
530 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
531 stream_->PopulateNetErrorDetails(&details);
532 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
533}
534
rch11a114a2014-09-04 23:41:59535// Regression test for http://crbug.com/409871
536TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
537 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45538 size_t spdy_request_headers_frame_length;
539 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
540 &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:59541 Initialize();
542
543 request_.method = "GET";
544 request_.url = GURL("http://www.google.com/");
545
rjshaded5ced072015-12-18 19:26:02546 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
547 callback_.callback()));
rch11a114a2014-09-04 23:41:59548
rjshaded5ced072015-12-18 19:26:02549 EXPECT_EQ(OK,
550 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:59551
552 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
553
554 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10555
556 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45557 // headers and payload.
558 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
559 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:10560 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:59561}
562
[email protected]1e960032013-12-20 19:00:20563TEST_P(QuicHttpStreamTest, SendPostRequest) {
564 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45565 size_t spdy_request_headers_frame_length;
566 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
567 &spdy_request_headers_frame_length));
[email protected]92bf17c2014-03-03 21:14:03568 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
[email protected]1e960032013-12-20 19:00:20569 AddWrite(ConstructAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:20570
571 Initialize();
572
olli.raula6df48b2a2015-11-26 07:40:22573 std::vector<scoped_ptr<UploadElementReader>> element_readers;
574 element_readers.push_back(make_scoped_ptr(
575 new UploadBytesElementReader(kUploadData, strlen(kUploadData))));
576 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:20577 request_.method = "POST";
578 request_.url = GURL("http://www.google.com/");
579 request_.upload_data_stream = &upload_data_stream;
[email protected]4db27d82012-12-20 11:50:24580 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
[email protected]f702d572012-12-04 15:56:20581
rjshaded5ced072015-12-18 19:26:02582 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
583 callback_.callback()));
584 EXPECT_EQ(OK,
585 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20586
587 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20588 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20589
590 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20591 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45592 size_t spdy_response_headers_frame_length;
593 ProcessPacket(ConstructResponseHeadersPacket(
594 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:20595
rchb27683c2015-07-29 23:53:50596 // The headers have arrived, but they are delivered asynchronously.
597 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
598 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36599 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20600 EXPECT_EQ(200, response_.headers->response_code());
601 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
602
603 // Send the response body.
604 const char kResponseBody[] = "Hello world!";
[email protected]92bf17c2014-03-03 21:14:03605 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:20606 // Since the body has already arrived, this should return immediately.
607 EXPECT_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());
sclittle1edeeb22015-09-02 20:46:10613
614 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45615 // headers and payload.
616 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
617 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:10618 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:45619 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
620 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10621 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20622}
623
[email protected]1e960032013-12-20 19:00:20624TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
625 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:47626 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:45627 size_t spdy_request_headers_frame_length;
628 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
629 &spdy_request_headers_frame_length));
[email protected]92bf17c2014-03-03 21:14:03630 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
rjshaded5ced072015-12-18 19:26:02631 AddWrite(
632 ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, kUploadData));
[email protected]1e960032013-12-20 19:00:20633 AddWrite(ConstructAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:47634 Initialize();
635
mmenkecbc2b712014-10-09 20:29:07636 ChunkedUploadDataStream upload_data_stream(0);
637 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:47638
639 request_.method = "POST";
640 request_.url = GURL("http://www.google.com/");
641 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07642 ASSERT_EQ(OK, request_.upload_data_stream->Init(
rjshaded5ced072015-12-18 19:26:02643 TestCompletionCallback().callback()));
[email protected]c9e49a02013-02-26 05:56:47644
rjshaded5ced072015-12-18 19:26:02645 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
646 callback_.callback()));
647 ASSERT_EQ(ERR_IO_PENDING,
648 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:47649
mmenkecbc2b712014-10-09 20:29:07650 upload_data_stream.AppendData(kUploadData, chunk_size, true);
rchb27683c2015-07-29 23:53:50651 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]c9e49a02013-02-26 05:56:47652
653 // Ack both packets in the request.
[email protected]1e960032013-12-20 19:00:20654 ProcessPacket(ConstructAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:47655
656 // Send the response headers (but not the body).
[email protected]1e960032013-12-20 19:00:20657 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45658 size_t spdy_response_headers_frame_length;
659 ProcessPacket(ConstructResponseHeadersPacket(
660 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:47661
rchb27683c2015-07-29 23:53:50662 // The headers have arrived, but they are delivered asynchronously
663 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
664 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]cadac622013-06-11 16:46:36665 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:47666 EXPECT_EQ(200, response_.headers->response_code());
667 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
668
669 // Send the response body.
670 const char kResponseBody[] = "Hello world!";
[email protected]1e960032013-12-20 19:00:20671 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
672 kResponseBody));
[email protected]c9e49a02013-02-26 05:56:47673
674 // Since the body has already arrived, this should return immediately.
675 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
676 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
677 callback_.callback()));
678
679 EXPECT_TRUE(stream_->IsResponseBodyComplete());
680 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10681
682 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45683 // headers and payload.
684 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
685 strlen(kUploadData) * 2),
sclittle1edeeb22015-09-02 20:46:10686 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:45687 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
688 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10689 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:47690}
691
[email protected]16ba7742014-08-22 00:57:25692TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
693 SetRequest("POST", "/", DEFAULT_PRIORITY);
694 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:45695 size_t spdy_request_headers_frame_length;
696 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
697 &spdy_request_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25698 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
699 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
700 AddWrite(ConstructAckPacket(4, 3, 1));
701 Initialize();
702
mmenkecbc2b712014-10-09 20:29:07703 ChunkedUploadDataStream upload_data_stream(0);
704 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:25705
706 request_.method = "POST";
707 request_.url = GURL("http://www.google.com/");
708 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07709 ASSERT_EQ(OK, request_.upload_data_stream->Init(
rjshaded5ced072015-12-18 19:26:02710 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25711
rjshaded5ced072015-12-18 19:26:02712 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
713 callback_.callback()));
714 ASSERT_EQ(ERR_IO_PENDING,
715 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:25716
mmenkecbc2b712014-10-09 20:29:07717 upload_data_stream.AppendData(nullptr, 0, true);
rchb27683c2015-07-29 23:53:50718 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25719
720 ProcessPacket(ConstructAckPacket(1, 0, 0));
721
722 // Send the response headers (but not the body).
723 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45724 size_t spdy_response_headers_frame_length;
725 ProcessPacket(ConstructResponseHeadersPacket(
726 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25727
rchb27683c2015-07-29 23:53:50728 // The headers have arrived, but they are delivered asynchronously
729 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
730 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25731 ASSERT_TRUE(response_.headers.get());
732 EXPECT_EQ(200, response_.headers->response_code());
733 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
734
735 // Send the response body.
736 const char kResponseBody[] = "Hello world!";
737 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
738 kResponseBody));
739
rchb27683c2015-07-29 23:53:50740 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:25741 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
742 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
743 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:25744 EXPECT_TRUE(stream_->IsResponseBodyComplete());
745 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10746
747 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45748 // headers and payload.
749 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
750 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:10751 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:45752 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
753 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10754 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:25755}
756
757TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
758 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45759 size_t spdy_request_headers_frame_length;
760 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
761 &spdy_request_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25762 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
763 AddWrite(ConstructAckPacket(3, 3, 1));
764 Initialize();
765
mmenkecbc2b712014-10-09 20:29:07766 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:25767
768 request_.method = "POST";
769 request_.url = GURL("http://www.google.com/");
770 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:07771 ASSERT_EQ(OK, request_.upload_data_stream->Init(
rjshaded5ced072015-12-18 19:26:02772 TestCompletionCallback().callback()));
[email protected]16ba7742014-08-22 00:57:25773
rjshaded5ced072015-12-18 19:26:02774 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
775 callback_.callback()));
776 ASSERT_EQ(ERR_IO_PENDING,
777 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:25778
mmenkecbc2b712014-10-09 20:29:07779 upload_data_stream.AppendData(nullptr, 0, true);
rchb27683c2015-07-29 23:53:50780 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25781
782 ProcessPacket(ConstructAckPacket(1, 0, 0));
783
784 // Send the response headers (but not the body).
785 SetResponse("200 OK", std::string());
sclittlec4dc1a32015-09-24 00:15:45786 size_t spdy_response_headers_frame_length;
787 ProcessPacket(ConstructResponseHeadersPacket(
788 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:25789
rchb27683c2015-07-29 23:53:50790 // The headers have arrived, but they are delivered asynchronously
791 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
792 EXPECT_EQ(OK, callback_.WaitForResult());
[email protected]16ba7742014-08-22 00:57:25793 ASSERT_TRUE(response_.headers.get());
794 EXPECT_EQ(200, response_.headers->response_code());
795 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
796
797 // Send the response body.
798 const char kResponseBody[] = "Hello world!";
799 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
800 kResponseBody));
801
rchb27683c2015-07-29 23:53:50802 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:25803 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
804 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
805 callback_.callback()));
806
807 EXPECT_TRUE(stream_->IsResponseBodyComplete());
808 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10809
810 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45811 // headers and payload.
812 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
813 stream_->GetTotalSentBytes());
814 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
815 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:10816 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:25817}
818
[email protected]1e960032013-12-20 19:00:20819TEST_P(QuicHttpStreamTest, DestroyedEarly) {
820 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45821 size_t spdy_request_headers_frame_length;
822 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
823 &spdy_request_headers_frame_length));
rtenneti4efd55dd2015-09-18 01:12:04824 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:00825 use_closing_stream_ = true;
826 Initialize();
827
828 request_.method = "GET";
829 request_.url = GURL("http://www.google.com/");
830
rjshaded5ced072015-12-18 19:26:02831 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, net_log_,
832 callback_.callback()));
833 EXPECT_EQ(OK,
834 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:00835
836 // Ack the request.
[email protected]1e960032013-12-20 19:00:20837 ProcessPacket(ConstructAckPacket(1, 0, 0));
rjshaded5ced072015-12-18 19:26:02838 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]63534512012-12-23 18:49:00839
840 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20841 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:00842 // In the course of processing this packet, the QuicHttpStream close itself.
sclittlec4dc1a32015-09-24 00:15:45843 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, nullptr));
[email protected]63534512012-12-23 18:49:00844
rchb27683c2015-07-29 23:53:50845 base::MessageLoop::current()->RunUntilIdle();
846
[email protected]63534512012-12-23 18:49:00847 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10848
849 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45850 // headers and payload.
851 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
852 stream_->GetTotalSentBytes());
853 // Zero since the stream is closed before processing the headers.
sclittle1edeeb22015-09-02 20:46:10854 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:00855}
856
[email protected]1e960032013-12-20 19:00:20857TEST_P(QuicHttpStreamTest, Priority) {
858 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:45859 size_t spdy_request_headers_frame_length;
860 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM,
861 &spdy_request_headers_frame_length));
rtenneti4efd55dd2015-09-18 01:12:04862 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:58863 use_closing_stream_ = true;
864 Initialize();
865
866 request_.method = "GET";
867 request_.url = GURL("http://www.google.com/");
868
rjshaded5ced072015-12-18 19:26:02869 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_,
870 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58871
872 // Check that priority is highest.
873 QuicReliableClientStream* reliable_stream =
874 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
875 DCHECK(reliable_stream);
zhongyib8677022015-12-01 05:51:30876 DCHECK_EQ(kV3HighestPriority, reliable_stream->Priority());
[email protected]24e5bc52013-09-18 15:36:58877
rjshaded5ced072015-12-18 19:26:02878 EXPECT_EQ(OK,
879 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58880
881 // Check that priority has now dropped back to MEDIUM.
ianswett0888cff2015-11-24 17:42:16882 DCHECK_EQ(MEDIUM,
883 ConvertQuicPriorityToRequestPriority(reliable_stream->Priority()));
[email protected]24e5bc52013-09-18 15:36:58884
885 // Ack the request.
[email protected]1e960032013-12-20 19:00:20886 ProcessPacket(ConstructAckPacket(1, 0, 0));
rjshaded5ced072015-12-18 19:26:02887 EXPECT_EQ(ERR_IO_PENDING, stream_->ReadResponseHeaders(callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:58888
889 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:20890 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:58891 // In the course of processing this packet, the QuicHttpStream close itself.
sclittlec4dc1a32015-09-24 00:15:45892 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, nullptr));
[email protected]24e5bc52013-09-18 15:36:58893
rchb27683c2015-07-29 23:53:50894 base::MessageLoop::current()->RunUntilIdle();
895
[email protected]24e5bc52013-09-18 15:36:58896 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10897
898 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45899 // headers and payload.
900 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
901 stream_->GetTotalSentBytes());
902 // Zero since the stream is closed before processing the headers.
sclittle1edeeb22015-09-02 20:46:10903 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:58904}
905
[email protected]e1cca9a2013-09-20 17:14:44906// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:20907TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
908 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:44909 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:52910
[email protected]08da9adb2014-04-24 08:33:31911 AddWrite(ConstructRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:52912
[email protected]e1cca9a2013-09-20 17:14:44913 Initialize();
914
915 request_.method = "GET";
916 request_.url = GURL("http://www.google.com/");
917
rjshaded5ced072015-12-18 19:26:02918 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_,
919 callback_.callback()));
[email protected]e1cca9a2013-09-20 17:14:44920
921 // Check that priority is highest.
922 QuicReliableClientStream* reliable_stream =
923 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
924 DCHECK(reliable_stream);
925 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
926 DCHECK(delegate);
zhongyib8677022015-12-01 05:51:30927 DCHECK_EQ(kV3HighestPriority, reliable_stream->Priority());
[email protected]e1cca9a2013-09-20 17:14:44928
ianswett0888cff2015-11-24 17:42:16929 // Set Delegate to nullptr and make sure Priority returns highest
[email protected]e1cca9a2013-09-20 17:14:44930 // priority.
rtennetibe635732014-10-02 22:51:42931 reliable_stream->SetDelegate(nullptr);
zhongyib8677022015-12-01 05:51:30932 DCHECK_EQ(kV3HighestPriority, reliable_stream->Priority());
[email protected]e1cca9a2013-09-20 17:14:44933 reliable_stream->SetDelegate(delegate);
sclittle1edeeb22015-09-02 20:46:10934
sclittle1edeeb22015-09-02 20:46:10935 EXPECT_EQ(0, stream_->GetTotalSentBytes());
936 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]e1cca9a2013-09-20 17:14:44937}
938
[email protected]f702d572012-12-04 15:56:20939} // namespace test
[email protected]f702d572012-12-04 15:56:20940} // namespace net